diff --git a/Documentation/Examples/CMakeLists.txt b/Documentation/Examples/CMakeLists.txt
index ee95e2e89956ec8ca79ce7b90f890a166aa7bb69..d0df09bf4a82f7d48978fa201a7289ec5b195e6d 100644
--- a/Documentation/Examples/CMakeLists.txt
+++ b/Documentation/Examples/CMakeLists.txt
@@ -100,6 +100,7 @@ if (Pythia8_FOUND)
     ProcessTrackingLine
     ProcessParticleCut
     ProcessStackInspector
+    ProcessLongitudinalProfile
     CORSIKAprocesses
     CORSIKAcascade
     CORSIKAparticles
diff --git a/Documentation/Examples/cascade_example.cc b/Documentation/Examples/cascade_example.cc
index f5c09343babcf62f87135a2fadb124c74a144f7e..b46e402dc789c4e5b5d65b4bf40602e0d7414d4f 100644
--- a/Documentation/Examples/cascade_example.cc
+++ b/Documentation/Examples/cascade_example.cc
@@ -21,6 +21,7 @@
 #include <corsika/environment/Environment.h>
 #include <corsika/environment/HomogeneousMedium.h>
 #include <corsika/environment/NuclearComposition.h>
+#include <corsika/environment/ShowerAxis.h>
 
 #include <corsika/geometry/Sphere.h>
 
@@ -107,6 +108,8 @@ int main() {
       rootCS, 0_m, 0_m,
       height_atmosphere); // this is the CORSIKA 7 start of atmosphere/universe
 
+  ShowerAxis const showerAxis{injectionPos, Vector{rootCS, 0_m, 0_m, -5000_km}, env};
+
   {
     auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) {
       return sqrt((Elab - m) * (Elab + m));
@@ -141,8 +144,7 @@ int main() {
   process::particle_cut::ParticleCut cut(80_GeV);
 
   process::track_writer::TrackWriter trackWriter("tracks.dat");
-  process::energy_loss::EnergyLoss eLoss(
-      injectionPos, geometry::Vector<dimensionless_d>(rootCS, {0, 0, -1}));
+  process::energy_loss::EnergyLoss eLoss{showerAxis};
 
   // assemble all processes into an ordered process list
   auto sequence = stackInspect << sibyll << sibyllNuc << decay << eLoss << cut
diff --git a/Documentation/Examples/stopping_power.cc b/Documentation/Examples/stopping_power.cc
index 5e2423b0c63c557ccf18369677fb1bff5be5b1e5..ffd1f05639b9112c7c6fb9eef3f54d8b51e7e3bf 100644
--- a/Documentation/Examples/stopping_power.cc
+++ b/Documentation/Examples/stopping_power.cc
@@ -9,6 +9,9 @@
  */
 
 #include <corsika/environment/Environment.h>
+#include <corsika/environment/HomogeneousMedium.h>
+#include <corsika/environment/IMediumModel.h>
+#include <corsika/environment/ShowerAxis.h>
 #include <corsika/geometry/Sphere.h>
 #include <corsika/process/energy_loss/EnergyLoss.h>
 #include <corsika/setup/SetupStack.h>
@@ -35,8 +38,10 @@ int main() {
   feenableexcept(FE_INVALID);
 
   // setup environment, geometry
-  using EnvType = Environment<setup::IEnvironmentModel>;
+  using EnvType = Environment<IMediumModel>;
   EnvType env;
+  env.GetUniverse()->SetModelProperties<HomogeneousMedium<IMediumModel>>(
+      1_g / cube(1_cm), NuclearComposition{{particles::Code::Unknown}, {1.f}});
 
   const CoordinateSystem& rootCS = env.GetCoordinateSystem();
 
@@ -44,9 +49,9 @@ int main() {
       rootCS, 0_m, 0_m,
       112.8_km); // this is the CORSIKA 7 start of atmosphere/universe
 
-  Vector<dimensionless_d> showerAxis(rootCS, {0, 0, -1});
-
-  process::energy_loss::EnergyLoss eLoss(injectionPos, showerAxis);
+  environment::ShowerAxis showerAxis{injectionPos,
+                                     Vector<length_d>{rootCS, 0_m, 0_m, 1_m}, env};
+  process::energy_loss::EnergyLoss eLoss{showerAxis};
 
   setup::Stack stack;
 
diff --git a/Documentation/Examples/vertical_EAS.cc b/Documentation/Examples/vertical_EAS.cc
index 2cdb101b631f592111452c88738a43715916d7a9..8a22dfc80a9948d71a3dd0f4719b64449893ccd1 100644
--- a/Documentation/Examples/vertical_EAS.cc
+++ b/Documentation/Examples/vertical_EAS.cc
@@ -13,12 +13,14 @@
 #include <corsika/environment/FlatExponential.h>
 #include <corsika/environment/LayeredSphericalAtmosphereBuilder.h>
 #include <corsika/environment/NuclearComposition.h>
+#include <corsika/environment/ShowerAxis.h>
 #include <corsika/geometry/Plane.h>
 #include <corsika/geometry/Sphere.h>
 #include <corsika/process/ProcessSequence.h>
 #include <corsika/process/StackProcess.h>
 #include <corsika/process/energy_loss/EnergyLoss.h>
 #include <corsika/process/interaction_counter/InteractionCounter.h>
+#include <corsika/process/longitudinal_profile/LongitudinalProfile.h>
 #include <corsika/process/observation_plane/ObservationPlane.h>
 #include <corsika/process/particle_cut/ParticleCut.h>
 #include <corsika/process/pythia/Decay.h>
@@ -75,8 +77,8 @@ int main(int argc, char** argv) {
   using EnvType = Environment<setup::IEnvironmentModel>;
   EnvType env;
   const CoordinateSystem& rootCS = env.GetCoordinateSystem();
-
-  environment::LayeredSphericalAtmosphereBuilder builder(Point{rootCS, 0_m, 0_m, 0_m});
+  Point const center{rootCS, 0_m, 0_m, 0_m};
+  environment::LayeredSphericalAtmosphereBuilder builder{center};
   builder.setNuclearComposition(
       {{particles::Code::Nitrogen, particles::Code::Oxygen},
        {0.7847f, 1.f - 0.7847f}}); // values taken from AIRES manual, Ar removed for now
@@ -98,28 +100,34 @@ int main(int argc, char** argv) {
   auto const mass = particles::GetNucleusMass(A, Z);
   const HEPEnergyType E0 = 1_GeV * std::stof(std::string(argv[3]));
   double theta = 0.;
-  double phi = 0.;
-
-  Point const injectionPos(
-      rootCS, 0_m, 0_m,
-      112.7_km +
-          builder.earthRadius); // this is the CORSIKA 7 start of atmosphere/universe
+  auto const thetaRad = theta / 180. * M_PI;
 
-  //  {
   auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) {
     return sqrt((Elab - m) * (Elab + m));
   };
   HEPMomentumType P0 = elab2plab(E0, mass);
-  auto momentumComponents = [](double theta, double phi, HEPMomentumType ptot) {
-    return std::make_tuple(ptot * sin(theta) * cos(phi), ptot * sin(theta) * sin(phi),
-                           -ptot * cos(theta));
+  auto momentumComponents = [](double thetaRad, HEPMomentumType ptot) {
+    return std::make_tuple(ptot * sin(thetaRad), 0_eV, -ptot * cos(thetaRad));
   };
-  auto const [px, py, pz] =
-      momentumComponents(theta / 180. * M_PI, phi / 180. * M_PI, P0);
+
+  auto const [px, py, pz] = momentumComponents(thetaRad, P0);
   auto plab = corsika::stack::MomentumVector(rootCS, {px, py, pz});
   cout << "input particle: " << beamCode << endl;
-  cout << "input angles: theta=" << theta << " phi=" << phi << endl;
-  cout << "input momentum: " << plab.GetComponents() / 1_GeV << endl;
+  cout << "input angles: theta=" << theta << endl;
+  cout << "input momentum: " << plab.GetComponents() / 1_GeV << ", norm = " << plab.norm()
+       << endl;
+
+  auto const observationHeight = 1.4_km + builder.earthRadius;
+  auto const injectionHeight = 112.75_km + builder.earthRadius;
+  auto const t = -observationHeight * cos(thetaRad) +
+                 sqrt(-si::detail::static_pow<2>(sin(thetaRad) * observationHeight) +
+                      si::detail::static_pow<2>(injectionHeight));
+  Point const showerCore{rootCS, 0_m, 0_m, observationHeight};
+  Point const injectionPos =
+      showerCore +
+      Vector<dimensionless_d>{rootCS, {-sin(thetaRad), 0, cos(thetaRad)}} * t;
+
+  std::cout << "point of injection: " << injectionPos.GetCoordinates() << std::endl;
 
   if (A != 1) {
     stack.AddParticle(std::tuple<particles::Code, units::si::HEPEnergyType,
@@ -134,12 +142,11 @@ int main(int argc, char** argv) {
             particles::Code::Proton, E0, plab, injectionPos, 0_ns});
   }
 
-  Line const line(injectionPos, plab.normalized() * 1_m * 1_Hz);
-  auto const velocity = line.GetV0().norm();
-
-  auto const observationHeight = 1.4_km + builder.earthRadius;
+  std::cout << "shower axis length: " << (showerCore - injectionPos).norm() * 1.02
+            << std::endl;
 
-  setup::Trajectory const showerAxis(line, (112.7_km - observationHeight) / velocity);
+  environment::ShowerAxis const showerAxis{injectionPos,
+                                           (showerCore - injectionPos) * 1.02, env};
 
   // setup processes, decays and interactions
 
@@ -152,44 +159,29 @@ int main(int argc, char** argv) {
   process::pythia::Decay decayPythia;
 
   // use sibyll decay routine for decays of particles unknown to pythia
-  process::sibyll::Decay decaySibyll({
-      Code::N1440Plus,
-      Code::N1440MinusBar,
-      Code::N1440_0,
-      Code::N1440_0Bar,
-      Code::N1710Plus,
-      Code::N1710MinusBar,
-      Code::N1710_0,
-      Code::N1710_0Bar,
-
-      Code::Pi1300Plus,
-      Code::Pi1300Minus,
-      Code::Pi1300_0,
-
-      Code::KStar0_1430_0,
-      Code::KStar0_1430_0Bar,
-      Code::KStar0_1430_Plus,
-      Code::KStar0_1430_MinusBar,
-  });
+  process::sibyll::Decay decaySibyll;
   decaySibyll.PrintDecayConfig();
 
-  process::particle_cut::ParticleCut cut(100_GeV);
+  process::particle_cut::ParticleCut cut{60_GeV};
 
   process::energy_loss::EnergyLoss eLoss(showerAxis);
+  process::longitudinal_profile::LongitudinalProfile longprof{showerAxis};
 
-  Plane const obsPlane(Point(rootCS, 0_m, 0_m, observationHeight),
-                       Vector<dimensionless_d>(rootCS, {0., 0., 1.}));
+  Plane const obsPlane(showerCore, Vector<dimensionless_d>(rootCS, {0., 0., 1.}));
   process::observation_plane::ObservationPlane observationLevel(obsPlane,
                                                                 "particles.dat");
 
   // assemble all processes into an ordered process list
 
   process::UrQMD::UrQMD urqmd;
+  process::interaction_counter::InteractionCounter urqmdCounted{urqmd};
 
   auto sibyllSequence = sibyllNucCounted << sibyllCounted;
-  process::switch_process::SwitchProcess switchProcess(urqmd, sibyllSequence, 55_GeV);
+  process::switch_process::SwitchProcess switchProcess(urqmdCounted, sibyllSequence,
+                                                       55_GeV);
   auto decaySequence = decayPythia << decaySibyll;
-  auto sequence = switchProcess << decaySequence << eLoss << cut << observationLevel;
+  auto sequence = switchProcess << decaySequence << longprof << eLoss << cut
+                                << observationLevel;
 
   // define air shower object, run simulation
   tracking_line::TrackingLine tracking;
@@ -212,10 +204,13 @@ int main(int argc, char** argv) {
   cout << "total dEdX energy (GeV): " << eLoss.GetTotal() / 1_GeV << endl
        << "relative difference (%): " << eLoss.GetTotal() / E0 * 100 << endl;
 
-  auto const hists = sibyllCounted.GetHistogram() + sibyllNucCounted.GetHistogram();
+  auto const hists = sibyllCounted.GetHistogram() + sibyllNucCounted.GetHistogram() +
+                     urqmdCounted.GetHistogram();
   hists.saveLab("inthist_lab.txt");
   hists.saveCMS("inthist_cms.txt");
 
+  longprof.save("longprof.txt");
+
   std::ofstream finish("finished");
   finish << "run completed without error" << std::endl;
 }
diff --git a/Environment/CMakeLists.txt b/Environment/CMakeLists.txt
index f4b93c759a2f32128d98406b8e4130dd851b8c45..e01188125c647e1f802edf844ce69b7014e70a49 100644
--- a/Environment/CMakeLists.txt
+++ b/Environment/CMakeLists.txt
@@ -1,6 +1,7 @@
 set (
   ENVIRONMENT_SOURCES
   LayeredSphericalAtmosphereBuilder.cc
+  ShowerAxis.cc
 )
 
 set (
@@ -19,6 +20,7 @@ set (
   FlatExponential.h
   SlidingPlanarExponential.h
   LayeredSphericalAtmosphereBuilder.h
+  ShowerAxis.h
   )
 
 set (
diff --git a/Environment/ShowerAxis.cc b/Environment/ShowerAxis.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3ae28638aa8871c04704de5264bdfd42788fe276
--- /dev/null
+++ b/Environment/ShowerAxis.cc
@@ -0,0 +1,46 @@
+/*
+ * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
+ *
+ * See file AUTHORS for a list of contributors.
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
+ * the license.
+ */
+
+#include <corsika/environment/ShowerAxis.h>
+#include <sstream>
+
+using namespace corsika::environment;
+using namespace corsika::units::si;
+
+GrammageType ShowerAxis::X(LengthType l) const {
+  auto const fractionalBin = l / steplength_;
+  int const lower = fractionalBin; // indices of nearest X support points
+  auto const lambda = fractionalBin - lower;
+  int const upper = lower + 1;
+
+  if (upper >= X_.size()) {
+    std::stringstream errormsg;
+    errormsg << "shower axis too short, cannot extrapolate (l / max_length_ = "
+             << l / max_length_ << ")";
+    throw std::runtime_error(errormsg.str().c_str());
+  } else if (lower < 0) {
+    throw std::runtime_error("cannot extrapolate to points behind point of injection");
+  }
+
+  assert(0 <= lambda && lambda <= 1.);
+  // linear interpolation between X[lower] and X[upper]
+  return X_[lower] * lambda + X_[upper] * (1 - lambda);
+}
+
+LengthType ShowerAxis::steplength() const { return steplength_; }
+
+GrammageType ShowerAxis::maximumX() const { return *X_.rbegin(); }
+
+GrammageType ShowerAxis::minimumX() const { return *X_.cbegin(); }
+
+GrammageType ShowerAxis::projectedX(geometry::Point const& p) const {
+  auto const projectedLength = (p - pointStart_).dot(axis_normalized_);
+  return X(projectedLength);
+}
diff --git a/Environment/ShowerAxis.h b/Environment/ShowerAxis.h
new file mode 100644
index 0000000000000000000000000000000000000000..3d31a0c7c9eb3a73b92c052c67ce6ce2d85febd8
--- /dev/null
+++ b/Environment/ShowerAxis.h
@@ -0,0 +1,96 @@
+/*
+ * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
+ *
+ * See file AUTHORS for a list of contributors.
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
+ * the license.
+ */
+
+#pragma once
+#include <corsika/environment/Environment.h>
+#include <corsika/geometry/Point.h>
+#include <corsika/geometry/Vector.h>
+#include <corsika/units/PhysicalUnits.h>
+
+#include <cassert>
+#include <cstdlib>
+#include <fstream>
+#include <functional>
+#include <iterator>
+#include <memory>
+#include <stdexcept>
+#include <vector>
+
+#include <boost/math/quadrature/gauss_kronrod.hpp>
+
+namespace corsika::environment {
+  class ShowerAxis {
+  public:
+    template <typename TEnvModel>
+    ShowerAxis(geometry::Point const& pStart,
+               geometry::Vector<units::si::length_d> length,
+               environment::Environment<TEnvModel> const& env, int steps = 10'000)
+        : pointStart_(pStart)
+        , length_(length)
+        , max_length_(length_.norm())
+        , steplength_(max_length_ / steps)
+        , axis_normalized_(length / max_length_)
+        , X_(steps) {
+      auto const* const universe = env.GetUniverse().get();
+
+      auto rho = [pStart, length, universe](double x) {
+        auto const p = pStart + length * x;
+        auto const* node = universe->GetContainingNode(p);
+        return node->GetModelProperties().GetMassDensity(p).magnitude();
+      };
+
+      double error;
+      int k = 0;
+      for (int i = 1; i < steps; ++i) {
+        auto const x_prev = (i - 1) / (steps - 1.);
+        auto const d_prev = max_length_ * x_prev;
+        auto const x = i / (steps - 1.);
+        auto const r = boost::math::quadrature::gauss_kronrod<double, 15>::integrate(
+            rho, x_prev, x, 15, 1e-9, &error);
+        auto const result =
+            units::si::MassDensityType(phys::units::detail::magnitude_tag, r) *
+            max_length_;
+        auto const resultTotal = result + X_[i - 1];
+        X_[i] = resultTotal;
+
+        for (; resultTotal > k * X_binning_; ++k) {
+          d_.emplace_back(d_prev + k * X_binning_ * steplength_ / result);
+        }
+      }
+
+      assert(std::is_sorted(X_.cbegin(), X_.cend()));
+      assert(std::is_sorted(d_.cbegin(), d_.cend()));
+    }
+
+    units::si::LengthType steplength() const;
+
+    units::si::GrammageType maximumX() const;
+
+    units::si::GrammageType minimumX() const;
+
+    units::si::GrammageType projectedX(geometry::Point const& p) const;
+
+    units::si::GrammageType X(units::si::LengthType) const;
+
+  private:
+    geometry::Point const pointStart_;
+    geometry::Vector<units::si::length_d> const length_;
+    units::si::LengthType const max_length_, steplength_;
+    geometry::Vector<units::si::dimensionless_d> const axis_normalized_;
+    std::vector<units::si::GrammageType> X_;
+
+    // for storing the lengths corresponding to equidistant X values
+    units::si::GrammageType const X_binning_ = std::invoke([]() {
+      using namespace units::si;
+      return 1_g / 1_cm / 1_cm;
+    });
+    std::vector<units::si::LengthType> d_;
+  };
+} // namespace corsika::environment
diff --git a/Processes/CMakeLists.txt b/Processes/CMakeLists.txt
index 6e93793eceed7a20cdaf7363dd585cc93b1afbac..d9083f29920de52f0391ed39f25d2b904ea15a98 100644
--- a/Processes/CMakeLists.txt
+++ b/Processes/CMakeLists.txt
@@ -13,6 +13,7 @@ add_subdirectory (UrQMD)
 
 # continuous physics
 add_subdirectory (EnergyLoss)
+add_subdirectory (LongitudinalProfile)
 add_subdirectory (TrackWriter)
 add_subdirectory (ObservationPlane)
 # stack processes
diff --git a/Processes/EnergyLoss/EnergyLoss.cc b/Processes/EnergyLoss/EnergyLoss.cc
index 749e574a25e64d6626c45bca7649b5b355e1d746..9bc1d8e86032a36e76c197f32f2b8c753df84eb2 100644
--- a/Processes/EnergyLoss/EnergyLoss.cc
+++ b/Processes/EnergyLoss/EnergyLoss.cc
@@ -21,6 +21,7 @@
 #include <fstream>
 #include <iostream>
 #include <limits>
+#include <numeric>
 
 using namespace std;
 
@@ -29,248 +30,236 @@ using namespace corsika::units::si;
 using SetupParticle = corsika::setup::Stack::ParticleType;
 using SetupTrack = corsika::setup::Trajectory;
 
-namespace corsika::process::energy_loss {
+using namespace corsika::process::energy_loss;
 
-  auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) {
-    return sqrt((Elab - m) * (Elab + m));
-  };
-
-  /**
-   *   PDG2018, passage of particles through matter
-   *
-   * Note, that \f$I_{\mathrm{eff}}\f$ of composite media a determined from \f$ \ln I =
-   * \sum_i a_i \ln(I_i) \f$ where \f$ a_i \f$ is the fraction of the electron population
-   * (\f$\sim Z_i\f$) of the \f$i\f$-th element. This can also be used for shell
-   * corrections or density effects.
-   *
-   * The \f$I_{\mathrm{eff}}\f$ of compounds is not better than a few percent, if not
-   * measured explicitly.
-   *
-   * For shell correction, see Sec 6 of https://www.nap.edu/read/20066/chapter/8#115
-   *
-   */
-  HEPEnergyType EnergyLoss::BetheBloch(SetupParticle const& p, GrammageType const dX) {
-
-    // all these are material constants and have to come through Environment
-    // right now: values for nitrogen_D
-    // 7 nitrogen_gas 82.0 0.49976 D E 0.0011653 0.0 1.7378 4.1323 0.15349 3.2125 10.54
-    auto Ieff = 82.0_eV;
-    [[maybe_unused]] auto Zmat = 7;
-    auto ZoverA = 0.49976_mol / 1_g;
-    const double x0 = 1.7378;
-    const double x1 = 4.1323;
-    const double Cbar = 10.54;
-    const double delta0 = 0.0;
-    const double aa = 0.15349;
-    const double sk = 3.2125;
-    // end of material constants
-
-    // this is the Bethe-Bloch coefficiet 4pi N_A r_e^2 m_e c^2
-    auto constexpr K = 0.307075_MeV / 1_mol * square(1_cm);
-    HEPEnergyType const E = p.GetEnergy();
-    HEPMassType const m = p.GetMass();
-    double const gamma = E / m;
-    int const Z = p.GetChargeNumber();
-    int const Z2 = Z * Z;
-    HEPMassType constexpr me = particles::Electron::GetMass();
-    auto const m2 = m * m;
-    auto constexpr me2 = me * me;
-    double const gamma2 = gamma * gamma;
-
-    double const beta2 = (gamma2 - 1) / gamma2; // 1-1/gamma2    (1-1/gamma)*(1+1/gamma);
-                                                // (gamma_2-1)/gamma_2 = (1-1/gamma2);
-    double constexpr c2 = 1;                    // HEP convention here c=c2=1
-    cout << "BetheBloch beta2=" << beta2 << " gamma2=" << gamma2 << endl;
-    [[maybe_unused]] double const eta2 = beta2 / (1 - beta2);
-    HEPMassType const Wmax =
-        2 * me * c2 * beta2 * gamma2 / (1 + 2 * gamma * me / m + me2 / m2);
-    // approx, but <<1%    HEPMassType const Wmax = 2*me*c2*beta2*gamma2;      for HEAVY
-    // PARTICLES Wmax ~ 2me v2 for non-relativistic particles
-    cout << "BetheBloch Wmax=" << Wmax << endl;
-
-    // Sternheimer parameterization, density corrections towards high energies
-    // NOTE/TODO: when Cbar is 0 it needs to be approximated from parameterization ->
-    // MISSING
-    cout << "BetheBloch p.GetMomentum().GetNorm()/m=" << p.GetMomentum().GetNorm() / m
-         << endl;
-    double const x = log10(p.GetMomentum().GetNorm() / m);
-    double delta = 0;
-    if (x >= x1) {
-      delta = 2 * (log(10)) * x - Cbar;
-    } else if (x < x1 && x >= x0) {
-      delta = 2 * (log(10)) * x - Cbar + aa * pow((x1 - x), sk);
-    } else if (x < x0) { // and IF conductor (otherwise, this is 0)
-      delta = delta0 * pow(100, 2 * (x - x0));
-    }
-    cout << "BetheBloch delta=" << delta << endl;
-
-    // with further low energies correction, accurary ~1% down to beta~0.05 (1MeV for p)
-
-    // shell correction, <~100MeV
-    // need more clarity about formulas and units
-    const double Cadj = 0;
-    /*
-    // https://www.nap.edu/read/20066/chapter/8#104
-    HEPEnergyType Iadj = 12_eV * Z + 7_eV;  // Iadj<163eV
-    if (Iadj>=163_eV)
-      Iadj = 9.76_eV * Z + 58.8_eV * pow(Z, -0.19);  // Iadj>=163eV
-    double const Cadj = (0.422377/eta2 + 0.0304043/(eta2*eta2) -
-    0.00038106/(eta2*eta2*eta2)) * 1e-6 * Iadj*Iadj + (3.858019/eta2 -
-    0.1667989/(eta2*eta2) + 0.00157955/(eta2*eta2*eta2)) * 1e-9 * Iadj*Iadj*Iadj;
-    */
-
-    // Barkas correction O(Z3) higher-order Born approximation
-    // see Appl. Phys. 85 (1999) 1249
-    // double A = 1;
-    // if (p.GetPID() == particles::Code::Nucleus) A = p.GetNuclearA();
-    // double const Erel = (p.GetEnergy()-p.GetMass()) / A / 1_keV;
-    // double const Llow = 0.01 * Erel;
-    // double const Lhigh = 1.5/pow(Erel, 0.4) + 45000./Zmat * pow(Erel, 1.6);
-    // double const barkas = Z * Llow*Lhigh/(Llow+Lhigh); // RU, I think the Z was
-    // missing...
-    double const barkas = 1; // does not work yet
-
-    // Bloch correction for O(Z4) higher-order Born approximation
-    // see Appl. Phys. 85 (1999) 1249
-    const double alpha = 1. / 137.035999173;
-    double const y2 = Z * Z * alpha * alpha / beta2;
-    double const bloch = -y2 * (1.202 - y2 * (1.042 - 0.855 * y2 + 0.343 * y2 * y2));
-
-    // cout << "BetheBloch Erel=" << Erel << " barkas=" << barkas << " bloch=" << bloch <<
-    // endl;
-
-    double const aux = 2 * me * c2 * beta2 * gamma2 * Wmax / (Ieff * Ieff);
-    return -K * Z2 * ZoverA / beta2 *
-           (0.5 * log(aux) - beta2 - Cadj / Z - delta / 2 + barkas + bloch) * dX;
-  }
-
-  // radiation losses according to PDG 2018, ch. 33 ref. [5]
-  HEPEnergyType EnergyLoss::RadiationLosses(SetupParticle const& vP,
-                                            GrammageType const vDX) {
-    // simple-minded hard-coded value for b(E) inspired by data from
-    // http://pdg.lbl.gov/2018/AtomicNuclearProperties/ for N and O.
-    auto constexpr b = 3.0 * 1e-6 * square(1_cm) / 1_g;
-    return -vP.GetEnergy() * b * vDX;
-  }
+EnergyLoss::EnergyLoss(environment::ShowerAxis const& shower_axis)
+    : shower_axis_(shower_axis)
+    , profile_(int(shower_axis.maximumX() / dX_) + 1) {}
 
-  HEPEnergyType EnergyLoss::TotalEnergyLoss(SetupParticle const& vP,
-                                            GrammageType const vDX) {
-    return BetheBloch(vP, vDX) + RadiationLosses(vP, vDX);
-  }
+auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) {
+  return sqrt((Elab - m) * (Elab + m));
+};
 
-  process::EProcessReturn EnergyLoss::DoContinuous(SetupParticle& p,
-                                                   SetupTrack const& t) {
-    if (p.GetChargeNumber() == 0) return process::EProcessReturn::eOk;
-
-    GrammageType const dX =
-        p.GetNode()->GetModelProperties().IntegratedGrammage(t, t.GetLength());
-    cout << "EnergyLoss " << p.GetPID() << ", z=" << p.GetChargeNumber()
-         << ", dX=" << dX / 1_g * square(1_cm) << "g/cm2" << endl;
-    HEPEnergyType dE = TotalEnergyLoss(p, dX);
-    auto E = p.GetEnergy();
-    const auto Ekin = E - p.GetMass();
-    auto Enew = E + dE;
-    cout << "EnergyLoss  dE=" << dE / 1_MeV << "MeV, "
-         << " E=" << E / 1_GeV << "GeV,  Ekin=" << Ekin / 1_GeV
-         << ", Enew=" << Enew / 1_GeV << "GeV" << endl;
-    auto status = process::EProcessReturn::eOk;
-    if (-dE > Ekin) {
-      dE = -Ekin;
-      Enew = p.GetMass();
-      status = process::EProcessReturn::eParticleAbsorbed;
-    }
-    p.SetEnergy(Enew);
-    MomentumUpdate(p, Enew);
-    EnergyLossTot_ += dE;
-    FillProfile(p, t, dE);
-    return status;
+/**
+ *   PDG2018, passage of particles through matter
+ *
+ * Note, that \f$I_{\mathrm{eff}}\f$ of composite media a determined from \f$ \ln I =
+ * \sum_i a_i \ln(I_i) \f$ where \f$ a_i \f$ is the fraction of the electron population
+ * (\f$\sim Z_i\f$) of the \f$i\f$-th element. This can also be used for shell
+ * corrections or density effects.
+ *
+ * The \f$I_{\mathrm{eff}}\f$ of compounds is not better than a few percent, if not
+ * measured explicitly.
+ *
+ * For shell correction, see Sec 6 of https://www.nap.edu/read/20066/chapter/8#115
+ *
+ */
+HEPEnergyType EnergyLoss::BetheBloch(SetupParticle const& p, GrammageType const dX) {
+
+  // all these are material constants and have to come through Environment
+  // right now: values for nitrogen_D
+  // 7 nitrogen_gas 82.0 0.49976 D E 0.0011653 0.0 1.7378 4.1323 0.15349 3.2125 10.54
+  auto Ieff = 82.0_eV;
+  [[maybe_unused]] auto Zmat = 7;
+  auto ZoverA = 0.49976_mol / 1_g;
+  const double x0 = 1.7378;
+  const double x1 = 4.1323;
+  const double Cbar = 10.54;
+  const double delta0 = 0.0;
+  const double aa = 0.15349;
+  const double sk = 3.2125;
+  // end of material constants
+
+  // this is the Bethe-Bloch coefficiet 4pi N_A r_e^2 m_e c^2
+  auto constexpr K = 0.307075_MeV / 1_mol * square(1_cm);
+  HEPEnergyType const E = p.GetEnergy();
+  HEPMassType const m = p.GetMass();
+  double const gamma = E / m;
+  int const Z = p.GetChargeNumber();
+  int const Z2 = Z * Z;
+  HEPMassType constexpr me = particles::Electron::GetMass();
+  auto const m2 = m * m;
+  auto constexpr me2 = me * me;
+  double const gamma2 = gamma * gamma;
+
+  double const beta2 = (gamma2 - 1) / gamma2; // 1-1/gamma2    (1-1/gamma)*(1+1/gamma);
+                                              // (gamma_2-1)/gamma_2 = (1-1/gamma2);
+  double constexpr c2 = 1;                    // HEP convention here c=c2=1
+  cout << "BetheBloch beta2=" << beta2 << " gamma2=" << gamma2 << endl;
+  [[maybe_unused]] double const eta2 = beta2 / (1 - beta2);
+  HEPMassType const Wmax =
+      2 * me * c2 * beta2 * gamma2 / (1 + 2 * gamma * me / m + me2 / m2);
+  // approx, but <<1%    HEPMassType const Wmax = 2*me*c2*beta2*gamma2;      for HEAVY
+  // PARTICLES Wmax ~ 2me v2 for non-relativistic particles
+  cout << "BetheBloch Wmax=" << Wmax << endl;
+
+  // Sternheimer parameterization, density corrections towards high energies
+  // NOTE/TODO: when Cbar is 0 it needs to be approximated from parameterization ->
+  // MISSING
+  cout << "BetheBloch p.GetMomentum().GetNorm()/m=" << p.GetMomentum().GetNorm() / m
+       << endl;
+  double const x = log10(p.GetMomentum().GetNorm() / m);
+  double delta = 0;
+  if (x >= x1) {
+    delta = 2 * (log(10)) * x - Cbar;
+  } else if (x < x1 && x >= x0) {
+    delta = 2 * (log(10)) * x - Cbar + aa * pow((x1 - x), sk);
+  } else if (x < x0) { // and IF conductor (otherwise, this is 0)
+    delta = delta0 * pow(100, 2 * (x - x0));
   }
-
-  LengthType EnergyLoss::MaxStepLength(SetupParticle const& vParticle,
-                                       SetupTrack const& vTrack) const {
-    if (vParticle.GetChargeNumber() == 0) {
-      return units::si::meter * std::numeric_limits<double>::infinity();
-    }
-
-    auto constexpr dX = 1_g / square(1_cm);
-    auto const dE = -TotalEnergyLoss(vParticle, dX); // dE > 0
-    //~ auto const Ekin = vParticle.GetEnergy() - vParticle.GetMass();
-    auto const maxLoss = 0.01 * vParticle.GetEnergy();
-    auto const maxGrammage = maxLoss / dE * dX;
-
-    return vParticle.GetNode()->GetModelProperties().ArclengthFromGrammage(vTrack,
-                                                                           maxGrammage) *
-           1.0001; // to make sure particle gets absorbed when DoContinuous() is called
+  cout << "BetheBloch delta=" << delta << endl;
+
+  // with further low energies correction, accurary ~1% down to beta~0.05 (1MeV for p)
+
+  // shell correction, <~100MeV
+  // need more clarity about formulas and units
+  const double Cadj = 0;
+  /*
+  // https://www.nap.edu/read/20066/chapter/8#104
+  HEPEnergyType Iadj = 12_eV * Z + 7_eV;  // Iadj<163eV
+  if (Iadj>=163_eV)
+    Iadj = 9.76_eV * Z + 58.8_eV * pow(Z, -0.19);  // Iadj>=163eV
+  double const Cadj = (0.422377/eta2 + 0.0304043/(eta2*eta2) -
+  0.00038106/(eta2*eta2*eta2)) * 1e-6 * Iadj*Iadj + (3.858019/eta2 -
+  0.1667989/(eta2*eta2) + 0.00157955/(eta2*eta2*eta2)) * 1e-9 * Iadj*Iadj*Iadj;
+  */
+
+  // Barkas correction O(Z3) higher-order Born approximation
+  // see Appl. Phys. 85 (1999) 1249
+  // double A = 1;
+  // if (p.GetPID() == particles::Code::Nucleus) A = p.GetNuclearA();
+  // double const Erel = (p.GetEnergy()-p.GetMass()) / A / 1_keV;
+  // double const Llow = 0.01 * Erel;
+  // double const Lhigh = 1.5/pow(Erel, 0.4) + 45000./Zmat * pow(Erel, 1.6);
+  // double const barkas = Z * Llow*Lhigh/(Llow+Lhigh); // RU, I think the Z was
+  // missing...
+  double const barkas = 1; // does not work yet
+
+  // Bloch correction for O(Z4) higher-order Born approximation
+  // see Appl. Phys. 85 (1999) 1249
+  const double alpha = 1. / 137.035999173;
+  double const y2 = Z * Z * alpha * alpha / beta2;
+  double const bloch = -y2 * (1.202 - y2 * (1.042 - 0.855 * y2 + 0.343 * y2 * y2));
+
+  // cout << "BetheBloch Erel=" << Erel << " barkas=" << barkas << " bloch=" << bloch <<
+  // endl;
+
+  double const aux = 2 * me * c2 * beta2 * gamma2 * Wmax / (Ieff * Ieff);
+  return -K * Z2 * ZoverA / beta2 *
+         (0.5 * log(aux) - beta2 - Cadj / Z - delta / 2 + barkas + bloch) * dX;
+}
+
+// radiation losses according to PDG 2018, ch. 33 ref. [5]
+HEPEnergyType EnergyLoss::RadiationLosses(SetupParticle const& vP,
+                                          GrammageType const vDX) {
+  // simple-minded hard-coded value for b(E) inspired by data from
+  // http://pdg.lbl.gov/2018/AtomicNuclearProperties/ for N and O.
+  auto constexpr b = 3.0 * 1e-6 * square(1_cm) / 1_g;
+  return -vP.GetEnergy() * b * vDX;
+}
+
+HEPEnergyType EnergyLoss::TotalEnergyLoss(SetupParticle const& vP,
+                                          GrammageType const vDX) {
+  return BetheBloch(vP, vDX) + RadiationLosses(vP, vDX);
+}
+
+process::EProcessReturn EnergyLoss::DoContinuous(SetupParticle& p, SetupTrack const& t) {
+  if (p.GetChargeNumber() == 0) return process::EProcessReturn::eOk;
+
+  GrammageType const dX =
+      p.GetNode()->GetModelProperties().IntegratedGrammage(t, t.GetLength());
+  cout << "EnergyLoss " << p.GetPID() << ", z=" << p.GetChargeNumber()
+       << ", dX=" << dX / 1_g * square(1_cm) << "g/cm2" << endl;
+  HEPEnergyType dE = TotalEnergyLoss(p, dX);
+  auto E = p.GetEnergy();
+  const auto Ekin = E - p.GetMass();
+  auto Enew = E + dE;
+  cout << "EnergyLoss  dE=" << dE / 1_MeV << "MeV, "
+       << " E=" << E / 1_GeV << "GeV,  Ekin=" << Ekin / 1_GeV << ", Enew=" << Enew / 1_GeV
+       << "GeV" << endl;
+  auto status = process::EProcessReturn::eOk;
+  if (-dE > Ekin) {
+    dE = -Ekin;
+    Enew = p.GetMass();
+    status = process::EProcessReturn::eParticleAbsorbed;
   }
-
-  void EnergyLoss::MomentumUpdate(corsika::setup::Stack::ParticleType& vP,
-                                  corsika::units::si::HEPEnergyType Enew) {
-    HEPMomentumType Pnew = elab2plab(Enew, vP.GetMass());
-    auto pnew = vP.GetMomentum();
-    vP.SetMomentum(pnew * Pnew / pnew.GetNorm());
+  p.SetEnergy(Enew);
+  MomentumUpdate(p, Enew);
+  FillProfile(t, dE);
+  return status;
+}
+
+LengthType EnergyLoss::MaxStepLength(SetupParticle const& vParticle,
+                                     SetupTrack const& vTrack) const {
+  if (vParticle.GetChargeNumber() == 0) {
+    return units::si::meter * std::numeric_limits<double>::infinity();
   }
 
-  void EnergyLoss::FillProfile(SetupParticle const& vP, SetupTrack const& vTrack,
-                               const HEPEnergyType dE) {
+  auto constexpr dX = 1_g / square(1_cm);
+  auto const dE = -TotalEnergyLoss(vParticle, dX); // dE > 0
+  //~ auto const Ekin = vParticle.GetEnergy() - vParticle.GetMass();
+  auto const maxLoss = 0.01 * vParticle.GetEnergy();
+  auto const maxGrammage = maxLoss / dE * dX;
 
-    using namespace corsika::geometry;
+  return vParticle.GetNode()->GetModelProperties().ArclengthFromGrammage(vTrack,
+                                                                         maxGrammage) *
+         1.0001; // to make sure particle gets absorbed when DoContinuous() is called
+}
 
-    auto const toStart = vTrack.GetPosition(0) - InjectionPoint_;
-    auto const toEnd = vTrack.GetPosition(1) - InjectionPoint_;
+void EnergyLoss::MomentumUpdate(corsika::setup::Stack::ParticleType& vP,
+                                corsika::units::si::HEPEnergyType Enew) {
+  HEPMomentumType Pnew = elab2plab(Enew, vP.GetMass());
+  auto pnew = vP.GetMomentum();
+  vP.SetMomentum(pnew * Pnew / pnew.GetNorm());
+}
 
-    auto const v1 = (toStart * 1_Hz).dot(ShowerAxisDirection_);
-    auto const v2 = (toEnd * 1_Hz).dot(ShowerAxisDirection_);
-    geometry::Line const lineToStartBin(InjectionPoint_, ShowerAxisDirection_ * v1);
-    geometry::Line const lineToEndBin(InjectionPoint_, ShowerAxisDirection_ * v2);
+void EnergyLoss::FillProfile(SetupTrack const& vTrack, const HEPEnergyType dE) {
 
-    SetupTrack const trajToStartBin(lineToStartBin, 1_s);
-    SetupTrack const trajToEndBin(lineToEndBin, 1_s);
+  GrammageType const grammageStart = shower_axis_.projectedX(vTrack.GetPosition(0));
+  GrammageType const grammageEnd = shower_axis_.projectedX(vTrack.GetPosition(1));
+  const auto deltaX = grammageEnd - grammageStart;
 
-    GrammageType const grammageStart =
-        vP.GetNode()->GetModelProperties().IntegratedGrammage(trajToStartBin,
-                                                              trajToStartBin.GetLength());
-    GrammageType const grammageEnd =
-        vP.GetNode()->GetModelProperties().IntegratedGrammage(trajToEndBin,
-                                                              trajToEndBin.GetLength());
+  const int binStart = grammageStart / dX_;
+  const int binEnd = grammageEnd / dX_;
 
-    const int binStart = grammageStart / dX_;
-    const int binEnd = grammageEnd / dX_;
+  std::cout << "energy deposit of " << -dE << " between " << grammageStart << " and "
+            << grammageEnd << std::endl;
 
-    std::cout << "energy deposit of " << -dE << " between " << grammageStart << " and "
-              << grammageEnd << std::endl;
+  auto energyCount = HEPEnergyType::zero();
 
-    auto energyCount = HEPEnergyType::zero();
+  auto fill = [&](int bin, GrammageType weight) {
+    if (deltaX > dX_threshold_) {
+      auto const increment = -dE * weight / deltaX;
+      profile_[bin] += increment;
+      energyCount += increment;
 
-    auto fill = [&](int bin, GrammageType weight) {
-      const auto dX = grammageEnd - grammageStart;
-      if (dX > dX_threshold_) {
-        auto const increment = -dE * weight / (grammageEnd - grammageStart);
-        Profile_[bin] += increment;
-        energyCount += increment;
+      std::cout << "filling bin " << bin << " with weight " << weight << ": " << increment
+                << std::endl;
+    }
+  };
 
-        std::cout << "filling bin " << bin << " with weight " << weight << ": "
-                  << increment << std::endl;
-      }
-    };
+  // fill longitudinal profile
+  fill(binStart, (1 + binStart) * dX_ - grammageStart);
+  fill(binEnd, grammageEnd - binEnd * dX_);
 
-    // fill longitudinal profile
-    fill(binStart, (1 + binStart) * dX_ - grammageStart);
-    fill(binEnd, grammageEnd - binEnd * dX_);
+  if (binStart == binEnd) { fill(binStart, -dX_); }
 
-    if (binStart == binEnd) { fill(binStart, -dX_); }
+  for (int bin = binStart + 1; bin < binEnd; ++bin) { fill(bin, dX_); }
 
-    for (int bin = binStart + 1; bin < binEnd; ++bin) { fill(bin, dX_); }
+  std::cout << "total energy added to histogram: " << energyCount << std::endl;
+}
 
-    std::cout << "total energy added to histogram: " << energyCount << std::endl;
-  }
-
-  void EnergyLoss::PrintProfile() const {
-    std::ofstream file("EnergyLossProfile.dat");
-    cout << "# EnergyLoss PrintProfile  X-bin [g/cm2]  dE/dX [GeV/g/cm2]  " << endl;
-    double const deltaX = dX_ / 1_g * square(1_cm);
-    for (auto v : Profile_) {
-      file << v.first * deltaX << " " << v.second / (deltaX * 1_GeV) << endl;
-    }
+void EnergyLoss::PrintProfile() const {
+  std::ofstream file("EnergyLossProfile.dat");
+  file << "# EnergyLoss profile" << std::endl
+       << "# lower X bin edge [g/cm2]  dE/dX [GeV/g/cm2]" << endl;
+  double const deltaX = dX_ / 1_g * square(1_cm);
+  for (size_t i = 0; i < profile_.size(); ++i) {
+    file << std::scientific << std::setw(15) << i * deltaX << std::setw(15)
+         << profile_.at(i) / (deltaX * 1_GeV) << endl;
   }
+}
 
-} // namespace corsika::process::energy_loss
+HEPEnergyType EnergyLoss::GetTotal() const {
+  return std::accumulate(profile_.cbegin(), profile_.cend(), HEPEnergyType::zero());
+}
diff --git a/Processes/EnergyLoss/EnergyLoss.h b/Processes/EnergyLoss/EnergyLoss.h
index ee4a707cf4890e529a763b5ebffd467dd6231de5..2e8e7955262bc2adf0f15aa6b9ff7ac6b10e1b64 100644
--- a/Processes/EnergyLoss/EnergyLoss.h
+++ b/Processes/EnergyLoss/EnergyLoss.h
@@ -11,6 +11,7 @@
 #ifndef _Processes_EnergyLoss_h_
 #define _Processes_EnergyLoss_h_
 
+#include <corsika/environment/ShowerAxis.h>
 #include <corsika/geometry/Point.h>
 #include <corsika/geometry/Vector.h>
 #include <corsika/process/ContinuousProcess.h>
@@ -31,21 +32,14 @@ namespace corsika::process::energy_loss {
     void MomentumUpdate(setup::Stack::ParticleType&, units::si::HEPEnergyType Enew);
 
   public:
-    template <typename TDim>
-    EnergyLoss(geometry::Point const& injectionPoint,
-               geometry::Vector<TDim> const& direction)
-        : InjectionPoint_(injectionPoint)
-        , ShowerAxisDirection_(direction.normalized()) {}
-
-    EnergyLoss(setup::Trajectory const& trajectory)
-        : EnergyLoss(trajectory.GetPosition(0), trajectory.GetV0()){};
+    EnergyLoss(environment::ShowerAxis const& showerAxis);
 
     void Init() {}
     process::EProcessReturn DoContinuous(setup::Stack::ParticleType&,
                                          setup::Trajectory const&);
     units::si::LengthType MaxStepLength(setup::Stack::ParticleType const&,
                                         setup::Trajectory const&) const;
-    units::si::HEPEnergyType GetTotal() const { return EnergyLossTot_; }
+    units::si::HEPEnergyType GetTotal() const;
     void PrintProfile() const;
     static units::si::HEPEnergyType BetheBloch(setup::Stack::ParticleType const&,
                                                const units::si::GrammageType);
@@ -55,22 +49,17 @@ namespace corsika::process::energy_loss {
                                                     const units::si::GrammageType);
 
   private:
-    void FillProfile(setup::Stack::ParticleType const&, setup::Trajectory const&,
-                     units::si::HEPEnergyType);
-    // void FillProfileAbsorbed(setup::Stack::ParticleType const&, setup::Trajectory
-    // const&);
+    void FillProfile(setup::Trajectory const&, units::si::HEPEnergyType);
 
-    units::si::HEPEnergyType EnergyLossTot_ = units::si::HEPEnergyType::zero();
     units::si::GrammageType const dX_ = std::invoke([]() {
       using namespace units::si;
       return 10_g / square(1_cm);
-    });                                               // profile binning
-    std::map<int, units::si::HEPEnergyType> Profile_; // longitudinal profile
-    geometry::Point const InjectionPoint_;
-    geometry::Vector<units::si::dimensionless_d> const ShowerAxisDirection_;
+    }); // profile binning
+    environment::ShowerAxis const& shower_axis_;
+    std::vector<units::si::HEPEnergyType> profile_; // longitudinal profile
   };
 
-  const units::si::GrammageType dX_threshold_ = std::invoke([]() {
+  units::si::GrammageType const dX_threshold_ = std::invoke([]() {
     using namespace units::si;
     return 0.0001_g / square(1_cm);
   });
diff --git a/Processes/LongitudinalProfile/CMakeLists.txt b/Processes/LongitudinalProfile/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..33e0df66db22b5b61174f72e7d887b83393abd82
--- /dev/null
+++ b/Processes/LongitudinalProfile/CMakeLists.txt
@@ -0,0 +1,62 @@
+set (
+  MODEL_SOURCES
+  LongitudinalProfile.cc
+  )
+
+set (
+  MODEL_HEADERS
+  LongitudinalProfile.h
+  )
+
+set (
+  MODEL_NAMESPACE
+  corsika/process/longitudinal_profile
+  )
+
+add_library (ProcessLongitudinalProfile STATIC ${MODEL_SOURCES})
+CORSIKA_COPY_HEADERS_TO_NAMESPACE (ProcessLongitudinalProfile ${MODEL_NAMESPACE} ${MODEL_HEADERS})
+
+set_target_properties (
+  ProcessLongitudinalProfile
+  PROPERTIES
+  VERSION ${PROJECT_VERSION}
+  SOVERSION 1
+#  PUBLIC_HEADER "${MODEL_HEADERS}"
+  )
+
+# target dependencies on other libraries (also the header onlys)
+target_link_libraries (
+  ProcessLongitudinalProfile
+  CORSIKAenvironment
+  CORSIKAunits
+  CORSIKAparticles
+  CORSIKAgeometry
+  CORSIKAsetup
+  )
+
+target_include_directories (
+  ProcessLongitudinalProfile 
+  INTERFACE 
+  $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>
+  $<INSTALL_INTERFACE:include/include>
+  )
+
+install (
+  TARGETS ProcessLongitudinalProfile
+  LIBRARY DESTINATION lib
+  ARCHIVE DESTINATION lib
+#  PUBLIC_HEADER DESTINATION include/${MODEL_NAMESPACE}
+  )
+
+
+# --------------------
+# code unit testing
+# CORSIKA_ADD_TEST(testNullModel)
+#target_link_libraries (
+#  testNullModel  ProcessNullModel
+#  CORSIKAsetup
+#  CORSIKAgeometry
+#  CORSIKAunits
+#  CORSIKAthirdparty # for catch2
+#  )
+
diff --git a/Processes/LongitudinalProfile/LongitudinalProfile.cc b/Processes/LongitudinalProfile/LongitudinalProfile.cc
new file mode 100644
index 0000000000000000000000000000000000000000..75b06031ca2a05061d273c99caaeb20872eccb72
--- /dev/null
+++ b/Processes/LongitudinalProfile/LongitudinalProfile.cc
@@ -0,0 +1,69 @@
+/*
+ * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
+ *
+ * See file AUTHORS for a list of contributors.
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
+ * the license.
+ */
+
+#include <corsika/process/longitudinal_profile/LongitudinalProfile.h>
+
+#include <corsika/particles/ParticleProperties.h>
+
+#include <corsika/setup/SetupStack.h>
+#include <corsika/setup/SetupTrajectory.h>
+
+#include <cmath>
+#include <iomanip>
+#include <limits>
+
+using namespace corsika::setup;
+using Particle = Stack::ParticleType;
+using Track = Trajectory;
+
+using namespace corsika::process::longitudinal_profile;
+using namespace corsika::units::si;
+
+LongitudinalProfile::LongitudinalProfile(environment::ShowerAxis const& shower_axis)
+    : shower_axis_{shower_axis}
+    , profiles_{static_cast<unsigned int>(shower_axis.maximumX() / dX_) + 1} {}
+
+void LongitudinalProfile::Init() {}
+
+template <>
+corsika::process::EProcessReturn LongitudinalProfile::DoContinuous(Particle const& vP,
+                                                                   Track const& vTrack) {
+  auto const pid = vP.GetPID();
+
+  GrammageType const grammageStart = shower_axis_.projectedX(vTrack.GetPosition(0));
+  GrammageType const grammageEnd = shower_axis_.projectedX(vTrack.GetPosition(1));
+
+  const int binStart = std::ceil(grammageStart / dX_);
+  const int binEnd = std::floor(grammageEnd / dX_);
+
+  for (int b = binStart; b <= binEnd; ++b) {
+    if (pid == particles::Code::MuPlus) {
+      profiles_.at(b)[ProfileIndex::MuPlus]++;
+    } else if (pid == particles::Code::MuMinus) {
+      profiles_.at(b)[ProfileIndex::MuMinus]++;
+    } else if (particles::IsHadron(pid)) {
+      profiles_.at(b)[ProfileIndex::Hadron]++;
+    }
+  }
+
+  return corsika::process::EProcessReturn::eOk;
+}
+
+void LongitudinalProfile::save(std::string const& filename) {
+  std::ofstream f{filename};
+  f << "# X / g·cm¯², mu+, mu-, all hadrons" << std::endl;
+  for (size_t b = 0; b < profiles_.size(); ++b) {
+    f << std::setprecision(5) << std::setw(11) << b * (dX_ / (1_g / 1_cm / 1_cm));
+    for (auto const& N : profiles_.at(b)) {
+      f << std::setw(width_) << std::setprecision(precision_) << std::scientific << N;
+    }
+    f << std::endl;
+  }
+}
diff --git a/Processes/LongitudinalProfile/LongitudinalProfile.h b/Processes/LongitudinalProfile/LongitudinalProfile.h
new file mode 100644
index 0000000000000000000000000000000000000000..68de7e0a042c71012bbf7da8d9518bc70fda412a
--- /dev/null
+++ b/Processes/LongitudinalProfile/LongitudinalProfile.h
@@ -0,0 +1,60 @@
+/*
+ * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
+ *
+ * See file AUTHORS for a list of contributors.
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
+ * the license.
+ */
+
+#ifndef _Processes_track_writer_LongitudinalProfile_h_
+#define _Processes_track_writer_LongitudinalProfile_h_
+
+#include <corsika/environment/ShowerAxis.h>
+#include <corsika/process/ContinuousProcess.h>
+#include <corsika/units/PhysicalUnits.h>
+
+#include <array>
+#include <fstream>
+#include <limits>
+#include <string>
+
+namespace corsika::process::longitudinal_profile {
+
+  class LongitudinalProfile
+      : public corsika::process::ContinuousProcess<LongitudinalProfile> {
+
+  public:
+    LongitudinalProfile(environment::ShowerAxis const&);
+
+    void Init();
+
+    template <typename Particle, typename Track>
+    corsika::process::EProcessReturn DoContinuous(Particle const&, Track const&);
+
+    template <typename Particle, typename Track>
+    corsika::units::si::LengthType MaxStepLength(Particle const&, Track const&) {
+      return units::si::meter * std::numeric_limits<double>::infinity();
+    }
+
+    void save(std::string const&);
+
+  private:
+    units::si::GrammageType const dX_ = std::invoke([]() {
+      using namespace units::si;
+      return 10_g / square(1_cm);
+    }); // profile binning
+
+    environment::ShowerAxis const& shower_axis_;
+    using ProfileEntry = std::array<uint32_t, 3>;
+    enum ProfileIndex { MuPlus = 0, MuMinus = 1, Hadron = 2 };
+    std::vector<ProfileEntry> profiles_; // longitudinal profile
+
+    static int const width_ = 14;
+    static int const precision_ = 6;
+  };
+
+} // namespace corsika::process::longitudinal_profile
+
+#endif
diff --git a/Processes/UrQMD/UrQMD.cc b/Processes/UrQMD/UrQMD.cc
index 1258c26329809906ca0e7dcff22b11c289580118..6f462878111a12b619e37718d18b769b8cd634b0 100644
--- a/Processes/UrQMD/UrQMD.cc
+++ b/Processes/UrQMD/UrQMD.cc
@@ -98,7 +98,7 @@ bool UrQMD::CanInteract(particles::Code vCode) const {
                    vCode) != std::cend(validProjectileCodes);
 }
 
-GrammageType UrQMD::GetInteractionLength(SetupParticle& vParticle) const {
+GrammageType UrQMD::GetInteractionLength(SetupParticle const& vParticle) const {
   if (!CanInteract(vParticle.GetPID())) {
     // we could do the canInteract check in GetCrossSection, too but if
     // we do it here we have the advantage of avoiding the loop
diff --git a/Processes/UrQMD/UrQMD.h b/Processes/UrQMD/UrQMD.h
index ea2526b9161099f3150771e8b69d676716fec170..402b16ca8e3f2b88b20ca6e4acca80066a040f04 100644
--- a/Processes/UrQMD/UrQMD.h
+++ b/Processes/UrQMD/UrQMD.h
@@ -27,7 +27,7 @@ namespace corsika::process::UrQMD {
     UrQMD();
     void Init() {}
     corsika::units::si::GrammageType GetInteractionLength(
-        corsika::setup::Stack::StackIterator&) const;
+        corsika::setup::Stack::StackIterator const&) const;
 
     template <typename TParticle>
     corsika::units::si::CrossSectionType GetCrossSection(TParticle const&,
diff --git a/ThirdParty/boost/atomic.hpp b/ThirdParty/boost/atomic.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1fd80d3c471ad74ed2a8c2730aaeea43ed072877
--- /dev/null
+++ b/ThirdParty/boost/atomic.hpp
@@ -0,0 +1,24 @@
+#ifndef BOOST_ATOMIC_HPP
+#define BOOST_ATOMIC_HPP
+
+//  Copyright (c) 2011 Helge Bahmann
+//  Copyright (c) 2020 Andrey Semashev
+//
+//  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)
+
+// This header includes all Boost.Atomic public headers
+
+#include <boost/memory_order.hpp>
+#include <boost/atomic/capabilities.hpp>
+#include <boost/atomic/atomic.hpp>
+#include <boost/atomic/atomic_ref.hpp>
+#include <boost/atomic/atomic_flag.hpp>
+#include <boost/atomic/fences.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#endif
diff --git a/ThirdParty/boost/atomic/atomic.hpp b/ThirdParty/boost/atomic/atomic.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..17ea197d7852c22e298e6f9e4eb6fdace8d4f246
--- /dev/null
+++ b/ThirdParty/boost/atomic/atomic.hpp
@@ -0,0 +1,96 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2011 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/atomic.hpp
+ *
+ * This header contains definition of \c atomic template and \c atomic_flag.
+ */
+
+#ifndef BOOST_ATOMIC_ATOMIC_HPP_INCLUDED_
+#define BOOST_ATOMIC_ATOMIC_HPP_INCLUDED_
+
+#include <boost/atomic/capabilities.hpp>
+#include <boost/atomic/detail/atomic_template.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+using atomics::atomic;
+
+using atomics::atomic_char;
+using atomics::atomic_uchar;
+using atomics::atomic_schar;
+using atomics::atomic_uint8_t;
+using atomics::atomic_int8_t;
+using atomics::atomic_ushort;
+using atomics::atomic_short;
+using atomics::atomic_uint16_t;
+using atomics::atomic_int16_t;
+using atomics::atomic_uint;
+using atomics::atomic_int;
+using atomics::atomic_uint32_t;
+using atomics::atomic_int32_t;
+using atomics::atomic_ulong;
+using atomics::atomic_long;
+using atomics::atomic_uint64_t;
+using atomics::atomic_int64_t;
+#ifdef BOOST_HAS_LONG_LONG
+using atomics::atomic_ullong;
+using atomics::atomic_llong;
+#endif
+using atomics::atomic_address;
+using atomics::atomic_bool;
+using atomics::atomic_wchar_t;
+#if !defined(BOOST_NO_CXX11_CHAR16_T)
+using atomics::atomic_char16_t;
+#endif
+#if !defined(BOOST_NO_CXX11_CHAR32_T)
+using atomics::atomic_char32_t;
+#endif
+
+using atomics::atomic_int_least8_t;
+using atomics::atomic_uint_least8_t;
+using atomics::atomic_int_least16_t;
+using atomics::atomic_uint_least16_t;
+using atomics::atomic_int_least32_t;
+using atomics::atomic_uint_least32_t;
+using atomics::atomic_int_least64_t;
+using atomics::atomic_uint_least64_t;
+using atomics::atomic_int_fast8_t;
+using atomics::atomic_uint_fast8_t;
+using atomics::atomic_int_fast16_t;
+using atomics::atomic_uint_fast16_t;
+using atomics::atomic_int_fast32_t;
+using atomics::atomic_uint_fast32_t;
+using atomics::atomic_int_fast64_t;
+using atomics::atomic_uint_fast64_t;
+using atomics::atomic_intmax_t;
+using atomics::atomic_uintmax_t;
+
+#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
+using atomics::atomic_float_t;
+using atomics::atomic_double_t;
+using atomics::atomic_long_double_t;
+#endif
+
+using atomics::atomic_size_t;
+using atomics::atomic_ptrdiff_t;
+
+#if defined(BOOST_HAS_INTPTR_T)
+using atomics::atomic_intptr_t;
+using atomics::atomic_uintptr_t;
+#endif
+
+} // namespace boost
+
+#endif // BOOST_ATOMIC_ATOMIC_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/atomic_flag.hpp b/ThirdParty/boost/atomic/atomic_flag.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..bde611478aab2820d44a451d29e7dad8998936e5
--- /dev/null
+++ b/ThirdParty/boost/atomic/atomic_flag.hpp
@@ -0,0 +1,32 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2011 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/atomic_flag.hpp
+ *
+ * This header contains definition of \c atomic_flag.
+ */
+
+#ifndef BOOST_ATOMIC_ATOMIC_FLAG_HPP_INCLUDED_
+#define BOOST_ATOMIC_ATOMIC_FLAG_HPP_INCLUDED_
+
+#include <boost/atomic/capabilities.hpp>
+#include <boost/atomic/detail/atomic_flag.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+using atomics::atomic_flag;
+
+} // namespace boost
+
+#endif // BOOST_ATOMIC_ATOMIC_FLAG_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/atomic_ref.hpp b/ThirdParty/boost/atomic/atomic_ref.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..fec1da847ac3db16ed5f6120a45848dd75820623
--- /dev/null
+++ b/ThirdParty/boost/atomic/atomic_ref.hpp
@@ -0,0 +1,30 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2020 Andrey Semashev
+ */
+/*!
+ * \file   atomic/atomic_ref.hpp
+ *
+ * This header contains definition of \c atomic_ref template.
+ */
+
+#ifndef BOOST_ATOMIC_ATOMIC_REF_HPP_INCLUDED_
+#define BOOST_ATOMIC_ATOMIC_REF_HPP_INCLUDED_
+
+#include <boost/atomic/capabilities.hpp>
+#include <boost/atomic/detail/atomic_ref_template.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+using atomics::atomic_ref;
+
+} // namespace boost
+
+#endif // BOOST_ATOMIC_ATOMIC_REF_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/capabilities.hpp b/ThirdParty/boost/atomic/capabilities.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5c7434d9bd0fd4b96f72c7c2bac723d585d8574e
--- /dev/null
+++ b/ThirdParty/boost/atomic/capabilities.hpp
@@ -0,0 +1,210 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/capabilities.hpp
+ *
+ * This header defines feature capabilities macros.
+ */
+
+#ifndef BOOST_ATOMIC_CAPABILITIES_HPP_INCLUDED_
+#define BOOST_ATOMIC_CAPABILITIES_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/platform.hpp>
+#include <boost/atomic/detail/int_sizes.hpp>
+#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
+#include <boost/atomic/detail/float_sizes.hpp>
+#endif
+
+#if !defined(BOOST_ATOMIC_EMULATED)
+#include BOOST_ATOMIC_DETAIL_BACKEND_HEADER(boost/atomic/detail/caps_)
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#ifndef BOOST_ATOMIC_INT8_LOCK_FREE
+#define BOOST_ATOMIC_INT8_LOCK_FREE 0
+#endif
+
+#ifndef BOOST_ATOMIC_INT16_LOCK_FREE
+#define BOOST_ATOMIC_INT16_LOCK_FREE 0
+#endif
+
+#ifndef BOOST_ATOMIC_INT32_LOCK_FREE
+#define BOOST_ATOMIC_INT32_LOCK_FREE 0
+#endif
+
+#ifndef BOOST_ATOMIC_INT64_LOCK_FREE
+#define BOOST_ATOMIC_INT64_LOCK_FREE 0
+#endif
+
+#ifndef BOOST_ATOMIC_INT128_LOCK_FREE
+#define BOOST_ATOMIC_INT128_LOCK_FREE 0
+#endif
+
+
+#ifndef BOOST_ATOMIC_CHAR_LOCK_FREE
+#define BOOST_ATOMIC_CHAR_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE
+#endif
+
+#ifndef BOOST_ATOMIC_CHAR16_T_LOCK_FREE
+#define BOOST_ATOMIC_CHAR16_T_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
+#endif
+
+#ifndef BOOST_ATOMIC_CHAR32_T_LOCK_FREE
+#define BOOST_ATOMIC_CHAR32_T_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
+#endif
+
+#ifndef BOOST_ATOMIC_WCHAR_T_LOCK_FREE
+#if BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 1
+#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 2
+#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 4
+#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 8
+#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
+#else
+#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 0
+#endif
+#endif
+
+#ifndef BOOST_ATOMIC_SHORT_LOCK_FREE
+#if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 1
+#define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 2
+#define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 4
+#define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 8
+#define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
+#else
+#define BOOST_ATOMIC_SHORT_LOCK_FREE 0
+#endif
+#endif
+
+#ifndef BOOST_ATOMIC_INT_LOCK_FREE
+#if BOOST_ATOMIC_DETAIL_SIZEOF_INT == 1
+#define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 2
+#define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 4
+#define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 8
+#define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
+#else
+#define BOOST_ATOMIC_INT_LOCK_FREE 0
+#endif
+#endif
+
+#ifndef BOOST_ATOMIC_LONG_LOCK_FREE
+#if BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 1
+#define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 2
+#define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 4
+#define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8
+#define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
+#else
+#define BOOST_ATOMIC_LONG_LOCK_FREE 0
+#endif
+#endif
+
+#ifndef BOOST_ATOMIC_LLONG_LOCK_FREE
+#if BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 1
+#define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 2
+#define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 4
+#define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 8
+#define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
+#else
+#define BOOST_ATOMIC_LLONG_LOCK_FREE 0
+#endif
+#endif
+
+#ifndef BOOST_ATOMIC_POINTER_LOCK_FREE
+#if (BOOST_ATOMIC_DETAIL_SIZEOF_POINTER + 0) == 8
+#define BOOST_ATOMIC_POINTER_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
+#elif (BOOST_ATOMIC_DETAIL_SIZEOF_POINTER + 0) == 4
+#define BOOST_ATOMIC_POINTER_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
+#else
+#define BOOST_ATOMIC_POINTER_LOCK_FREE 0
+#endif
+#endif
+
+#define BOOST_ATOMIC_ADDRESS_LOCK_FREE BOOST_ATOMIC_POINTER_LOCK_FREE
+
+#ifndef BOOST_ATOMIC_BOOL_LOCK_FREE
+// We store bools in 1-byte storage in all backends
+#define BOOST_ATOMIC_BOOL_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE
+#endif
+
+#ifndef BOOST_ATOMIC_FLAG_LOCK_FREE
+#define BOOST_ATOMIC_FLAG_LOCK_FREE BOOST_ATOMIC_BOOL_LOCK_FREE
+#endif
+
+#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
+
+#if !defined(BOOST_ATOMIC_FLOAT_LOCK_FREE) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT)
+#if BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 2
+#define BOOST_ATOMIC_FLOAT_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 4
+#define BOOST_ATOMIC_FLOAT_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 8
+#define BOOST_ATOMIC_FLOAT_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 16
+#define BOOST_ATOMIC_FLOAT_LOCK_FREE BOOST_ATOMIC_INT128_LOCK_FREE
+#else
+#define BOOST_ATOMIC_FLOAT_LOCK_FREE 0
+#endif
+#endif
+
+#if !defined(BOOST_ATOMIC_DOUBLE_LOCK_FREE) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE)
+#if BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 2
+#define BOOST_ATOMIC_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 4
+#define BOOST_ATOMIC_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 8
+#define BOOST_ATOMIC_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 16
+#define BOOST_ATOMIC_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT128_LOCK_FREE
+#else
+#define BOOST_ATOMIC_DOUBLE_LOCK_FREE 0
+#endif
+#endif
+
+#if !defined(BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE)
+#if BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 2
+#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 4
+#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 8
+#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 16
+#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE BOOST_ATOMIC_INT128_LOCK_FREE
+#else
+#define BOOST_ATOMIC_LONG_DOUBLE_LOCK_FREE 0
+#endif
+#endif
+
+#endif // !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
+
+#ifndef BOOST_ATOMIC_THREAD_FENCE
+#define BOOST_ATOMIC_THREAD_FENCE 0
+#endif
+
+#ifndef BOOST_ATOMIC_SIGNAL_FENCE
+#define BOOST_ATOMIC_SIGNAL_FENCE 0
+#endif
+
+#endif // BOOST_ATOMIC_CAPABILITIES_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/addressof.hpp b/ThirdParty/boost/atomic/detail/addressof.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..38e876e317e5cecd0568933696c1770bd99b12c9
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/addressof.hpp
@@ -0,0 +1,58 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/addressof.hpp
+ *
+ * This header defines \c addressof helper function. It is similar to \c boost::addressof but it is more
+ * lightweight and also contains a workaround for some compiler warnings.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_ADDRESSOF_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_ADDRESSOF_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+// Detection logic is based on boost/core/addressof.hpp
+#if defined(BOOST_MSVC_FULL_VER) && BOOST_MSVC_FULL_VER >= 190024215
+#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_ADDRESSOF
+#elif defined(BOOST_GCC) && BOOST_GCC >= 70000
+#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_ADDRESSOF
+#elif defined(__has_builtin)
+#if __has_builtin(__builtin_addressof)
+#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_ADDRESSOF
+#endif
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< typename T >
+BOOST_FORCEINLINE T* addressof(T& value) BOOST_NOEXCEPT
+{
+#if defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_ADDRESSOF)
+    return __builtin_addressof(value);
+#else
+    // Note: The point of using a local struct as the intermediate type instead of char is to avoid gcc warnings
+    // if T is a const volatile char*:
+    // warning: casting 'const volatile char* const' to 'const volatile char&' does not dereference pointer
+    // The local struct makes sure T is not related to the cast target type.
+    struct opaque_type;
+    return reinterpret_cast< T* >(&const_cast< opaque_type& >(reinterpret_cast< const volatile opaque_type& >(value)));
+#endif
+}
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_ADDRESSOF_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/atomic_flag.hpp b/ThirdParty/boost/atomic/detail/atomic_flag.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f17869b5fc47d7e6601fcb11e137e24131fb9d71
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/atomic_flag.hpp
@@ -0,0 +1,90 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/atomic_flag.hpp
+ *
+ * This header contains interface definition of \c atomic_flag.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_HPP_INCLUDED_
+
+#include <boost/assert.hpp>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/operations.hpp>
+#if defined(BOOST_ATOMIC_DETAIL_NO_CXX11_ALIGNAS)
+#include <boost/type_traits/type_with_alignment.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+/*
+ * IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE,
+ *                      see comment for convert_memory_order_to_gcc in ops_gcc_atomic.hpp.
+ */
+
+namespace boost {
+namespace atomics {
+
+#if defined(BOOST_ATOMIC_DETAIL_NO_CXX11_CONSTEXPR_UNION_INIT) || defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
+#define BOOST_ATOMIC_NO_ATOMIC_FLAG_INIT
+#else
+#define BOOST_ATOMIC_FLAG_INIT {}
+#endif
+
+struct atomic_flag
+{
+    typedef atomics::detail::operations< 1u, false > operations;
+    typedef operations::storage_type storage_type;
+
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_ALIGNAS)
+    alignas(operations::storage_alignment) storage_type m_storage;
+#else
+    // Note: Some compilers cannot use constant expressions in alignment attributes, so we have to use the union trick
+    union
+    {
+        storage_type m_storage;
+        boost::type_with_alignment< operations::storage_alignment >::type m_aligner;
+    };
+#endif
+
+    BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT atomic_flag() BOOST_NOEXCEPT : m_storage(0u)
+    {
+    }
+
+    BOOST_FORCEINLINE bool test(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_release);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+        return !!operations::load(m_storage, order);
+    }
+
+    BOOST_FORCEINLINE bool test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return operations::test_and_set(m_storage, order);
+    }
+
+    BOOST_FORCEINLINE void clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_consume);
+        BOOST_ASSERT(order != memory_order_acquire);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+        operations::clear(m_storage, order);
+    }
+
+    BOOST_DELETED_FUNCTION(atomic_flag(atomic_flag const&))
+    BOOST_DELETED_FUNCTION(atomic_flag& operator= (atomic_flag const&))
+};
+
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/atomic_ref_template.hpp b/ThirdParty/boost/atomic/detail/atomic_ref_template.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..262a62686c31af45c391e15b4ce00dfeee9326d8
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/atomic_ref_template.hpp
@@ -0,0 +1,1119 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2020 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/atomic_ref_template.hpp
+ *
+ * This header contains interface definition of \c atomic_ref template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_ATOMIC_REF_TEMPLATE_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_ATOMIC_REF_TEMPLATE_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/cstdint.hpp>
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/intptr.hpp>
+#include <boost/atomic/detail/classify.hpp>
+#include <boost/atomic/detail/addressof.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/bitwise_cast.hpp>
+#include <boost/atomic/detail/integral_conversions.hpp>
+#include <boost/atomic/detail/operations.hpp>
+#include <boost/atomic/detail/extra_operations.hpp>
+#include <boost/atomic/detail/memory_order_utils.hpp>
+#include <boost/atomic/detail/type_traits/is_signed.hpp>
+#include <boost/atomic/detail/type_traits/is_trivially_copyable.hpp>
+#include <boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp>
+#include <boost/atomic/detail/type_traits/alignment_of.hpp>
+#include <boost/atomic/detail/type_traits/conditional.hpp>
+#include <boost/atomic/detail/type_traits/integral_constant.hpp>
+#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
+#include <boost/atomic/detail/bitwise_fp_cast.hpp>
+#include <boost/atomic/detail/fp_operations.hpp>
+#include <boost/atomic/detail/extra_fp_operations.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(BOOST_MSVC)
+#pragma warning(push)
+// 'boost::atomics::atomic_ref<T>' : multiple assignment operators specified
+#pragma warning(disable: 4522)
+#endif
+
+/*
+ * IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE,
+ *                      see comment for convert_memory_order_to_gcc in ops_gcc_atomic.hpp.
+ */
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< typename T, bool IsSigned >
+struct is_atomic_ref_lock_free
+{
+    typedef T value_type;
+    typedef atomics::detail::operations< sizeof(value_type), IsSigned > operations;
+    typedef typename operations::storage_type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST bool value = sizeof(value_type) == sizeof(storage_type) && operations::is_always_lock_free;
+};
+
+template< typename T, bool IsSigned >
+class base_atomic_ref_common
+{
+public:
+    typedef T value_type;
+
+protected:
+    typedef typename atomics::detail::conditional<
+        atomics::detail::is_atomic_ref_lock_free< T, IsSigned >::value,
+        atomics::detail::operations< sizeof(value_type), IsSigned >,
+        atomics::detail::emulated_operations< sizeof(value_type), atomics::detail::alignment_of< value_type >::value, IsSigned >
+    >::type operations;
+    typedef typename atomics::detail::conditional< sizeof(value_type) <= sizeof(void*), value_type, value_type const& >::type value_arg_type;
+    typedef typename operations::storage_type storage_type;
+
+public:
+    static BOOST_CONSTEXPR_OR_CONST std::size_t required_alignment = atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment ? operations::storage_alignment : atomics::detail::alignment_of< value_type >::value;
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = operations::is_always_lock_free;
+
+protected:
+    value_type* m_value;
+
+public:
+    BOOST_FORCEINLINE explicit base_atomic_ref_common(value_type& v) BOOST_NOEXCEPT : m_value(atomics::detail::addressof(v))
+    {
+    }
+
+protected:
+    BOOST_FORCEINLINE storage_type& storage() const BOOST_NOEXCEPT
+    {
+        return *reinterpret_cast< storage_type* >(m_value);
+    }
+};
+
+#if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
+template< typename T, bool IsSigned >
+BOOST_CONSTEXPR_OR_CONST std::size_t base_atomic_ref_common< T, IsSigned >::required_alignment;
+template< typename T, bool IsSigned >
+BOOST_CONSTEXPR_OR_CONST bool base_atomic_ref_common< T, IsSigned >::is_always_lock_free;
+#endif
+
+
+template< typename T, typename Kind >
+class base_atomic_ref;
+
+//! General template. Implementation for user-defined types, such as structs and enums, and pointers to non-object types
+template< typename T >
+class base_atomic_ref< T, void > :
+    public base_atomic_ref_common< T, false >
+{
+private:
+    typedef base_atomic_ref_common< T, false > base_type;
+
+public:
+    typedef typename base_type::value_type value_type;
+
+protected:
+    typedef typename base_type::operations operations;
+    typedef typename base_type::storage_type storage_type;
+    typedef typename base_type::value_arg_type value_arg_type;
+
+private:
+    typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment > use_bitwise_cast;
+
+public:
+    BOOST_DEFAULTED_FUNCTION(base_atomic_ref(base_atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
+    BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
+    {
+    }
+
+    BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_consume);
+        BOOST_ASSERT(order != memory_order_acquire);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        operations::store(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_release);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        return atomics::detail::bitwise_cast< value_type >(operations::load(this->storage(), order));
+    }
+
+    BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
+    {
+        return atomics::detail::bitwise_cast< value_type >(operations::exchange(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
+    {
+        return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) const BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
+    {
+        return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
+
+private:
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
+    {
+        storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
+        const bool res = operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
+        expected = atomics::detail::bitwise_cast< value_type >(old_value);
+        return res;
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
+    {
+        storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
+        const bool res = operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
+        expected = atomics::detail::bitwise_cast< value_type >(old_value);
+        return res;
+    }
+};
+
+
+//! Implementation for integers
+template< typename T >
+class base_atomic_ref< T, int > :
+    public base_atomic_ref_common< T, atomics::detail::is_signed< T >::value >
+{
+private:
+    typedef base_atomic_ref_common< T, atomics::detail::is_signed< T >::value > base_type;
+
+public:
+    typedef typename base_type::value_type value_type;
+    typedef typename base_type::value_type difference_type;
+
+protected:
+    typedef typename base_type::operations operations;
+    typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations;
+    typedef typename base_type::storage_type storage_type;
+    typedef value_type value_arg_type;
+
+private:
+    typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment > use_bitwise_cast;
+
+public:
+    BOOST_DEFAULTED_FUNCTION(base_atomic_ref(base_atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
+    BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
+    {
+    }
+
+    // Standard methods
+    BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_consume);
+        BOOST_ASSERT(order != memory_order_acquire);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        operations::store(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_release);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        return atomics::detail::integral_truncate< value_type >(operations::load(this->storage(), order));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(operations::fetch_add(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(operations::fetch_sub(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(operations::exchange(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_and(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(operations::fetch_and(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_or(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(operations::fetch_or(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_xor(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(operations::fetch_xor(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    // Boost.Atomic extensions
+    BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::fetch_negate(this->storage(), order));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_complement(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::fetch_complement(this->storage(), order));
+    }
+
+    BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::add(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::sub(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::negate(this->storage(), order));
+    }
+
+    BOOST_FORCEINLINE value_type bitwise_and(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_and(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type bitwise_or(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_or(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type bitwise_xor(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_xor(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type bitwise_complement(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_complement(this->storage(), order));
+    }
+
+    BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_add(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_sub(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_negate(this->storage(), order);
+    }
+
+    BOOST_FORCEINLINE void opaque_and(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_and(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE void opaque_or(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_or(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE void opaque_xor(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_xor(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE void opaque_complement(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_complement(this->storage(), order);
+    }
+
+    BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return extra_operations::add_and_test(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return extra_operations::sub_and_test(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE bool negate_and_test(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return extra_operations::negate_and_test(this->storage(), order);
+    }
+
+    BOOST_FORCEINLINE bool and_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return extra_operations::and_and_test(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE bool or_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return extra_operations::or_and_test(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE bool xor_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return extra_operations::xor_and_test(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE bool complement_and_test(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return extra_operations::complement_and_test(this->storage(), order);
+    }
+
+    BOOST_FORCEINLINE bool bit_test_and_set(unsigned int bit_number, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
+        return extra_operations::bit_test_and_set(this->storage(), bit_number, order);
+    }
+
+    BOOST_FORCEINLINE bool bit_test_and_reset(unsigned int bit_number, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
+        return extra_operations::bit_test_and_reset(this->storage(), bit_number, order);
+    }
+
+    BOOST_FORCEINLINE bool bit_test_and_complement(unsigned int bit_number, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
+        return extra_operations::bit_test_and_complement(this->storage(), bit_number, order);
+    }
+
+    // Operators
+    BOOST_FORCEINLINE value_type operator++(int) BOOST_NOEXCEPT
+    {
+        return fetch_add(1);
+    }
+
+    BOOST_FORCEINLINE value_type operator++() BOOST_NOEXCEPT
+    {
+        return add(1);
+    }
+
+    BOOST_FORCEINLINE value_type operator--(int) BOOST_NOEXCEPT
+    {
+        return fetch_sub(1);
+    }
+
+    BOOST_FORCEINLINE value_type operator--() BOOST_NOEXCEPT
+    {
+        return sub(1);
+    }
+
+    BOOST_FORCEINLINE value_type operator+=(difference_type v) BOOST_NOEXCEPT
+    {
+        return add(v);
+    }
+
+    BOOST_FORCEINLINE value_type operator-=(difference_type v) BOOST_NOEXCEPT
+    {
+        return sub(v);
+    }
+
+    BOOST_FORCEINLINE value_type operator&=(value_type v) BOOST_NOEXCEPT
+    {
+        return bitwise_and(v);
+    }
+
+    BOOST_FORCEINLINE value_type operator|=(value_type v) BOOST_NOEXCEPT
+    {
+        return bitwise_or(v);
+    }
+
+    BOOST_FORCEINLINE value_type operator^=(value_type v) BOOST_NOEXCEPT
+    {
+        return bitwise_xor(v);
+    }
+
+    BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
+
+private:
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
+    {
+        storage_type old_value = static_cast< storage_type >(expected);
+        const bool res = operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
+        expected = atomics::detail::integral_truncate< value_type >(old_value);
+        return res;
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
+    {
+        storage_type old_value = static_cast< storage_type >(expected);
+        const bool res = operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
+        expected = atomics::detail::integral_truncate< value_type >(old_value);
+        return res;
+    }
+};
+
+//! Implementation for bool
+template< >
+class base_atomic_ref< bool, int > :
+    public base_atomic_ref_common< bool, false >
+{
+private:
+    typedef base_atomic_ref_common< bool, false > base_type;
+
+public:
+    typedef bool value_type;
+
+protected:
+    typedef base_type::operations operations;
+    typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations;
+    typedef base_type::storage_type storage_type;
+    typedef value_type value_arg_type;
+
+private:
+    typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment > use_bitwise_cast;
+
+public:
+    BOOST_DEFAULTED_FUNCTION(base_atomic_ref(base_atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
+    BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
+    {
+    }
+
+    // Standard methods
+    BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_consume);
+        BOOST_ASSERT(order != memory_order_acquire);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        operations::store(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_release);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        return !!operations::load(this->storage(), order);
+    }
+
+    BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return !!operations::exchange(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
+
+private:
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
+    {
+        storage_type old_value = static_cast< storage_type >(expected);
+        const bool res = operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
+        expected = !!old_value;
+        return res;
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
+    {
+        storage_type old_value = static_cast< storage_type >(expected);
+        const bool res = operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
+        expected = !!old_value;
+        return res;
+    }
+};
+
+
+#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
+
+//! Implementation for floating point types
+template< typename T >
+class base_atomic_ref< T, float > :
+    public base_atomic_ref_common< T, false >
+{
+private:
+    typedef base_atomic_ref_common< T, false > base_type;
+
+public:
+    typedef typename base_type::value_type value_type;
+    typedef typename base_type::value_type difference_type;
+
+protected:
+    typedef typename base_type::operations operations;
+    typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations;
+    typedef atomics::detail::fp_operations< extra_operations, value_type, operations::storage_size > fp_operations;
+    typedef atomics::detail::extra_fp_operations< fp_operations, value_type, operations::storage_size > extra_fp_operations;
+    typedef typename base_type::storage_type storage_type;
+    typedef value_type value_arg_type;
+
+private:
+    typedef atomics::detail::integral_constant< bool, atomics::detail::value_sizeof< value_type >::value != sizeof(storage_type) > has_padding_bits;
+    typedef atomics::detail::integral_constant< bool, has_padding_bits::value || atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment > use_bitwise_cast;
+
+public:
+    BOOST_DEFAULTED_FUNCTION(base_atomic_ref(base_atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
+    BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
+    {
+        this->clear_padding_bits(has_padding_bits());
+    }
+
+    BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_consume);
+        BOOST_ASSERT(order != memory_order_acquire);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        operations::store(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_release);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        return atomics::detail::bitwise_fp_cast< value_type >(operations::load(this->storage(), order));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return fp_operations::fetch_add(this->storage(), v, order);
+    }
+
+    BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return fp_operations::fetch_sub(this->storage(), v, order);
+    }
+
+    BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::bitwise_fp_cast< value_type >(operations::exchange(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    // Boost.Atomic extensions
+    BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return extra_fp_operations::fetch_negate(this->storage(), order);
+    }
+
+    BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return extra_fp_operations::add(this->storage(), v, order);
+    }
+
+    BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return extra_fp_operations::sub(this->storage(), v, order);
+    }
+
+    BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return extra_fp_operations::negate(this->storage(), order);
+    }
+
+    BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        extra_fp_operations::opaque_add(this->storage(), v, order);
+    }
+
+    BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        extra_fp_operations::opaque_sub(this->storage(), v, order);
+    }
+
+    BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        extra_fp_operations::opaque_negate(this->storage(), order);
+    }
+
+    // Operators
+    BOOST_FORCEINLINE value_type operator+=(difference_type v) BOOST_NOEXCEPT
+    {
+        return add(v);
+    }
+
+    BOOST_FORCEINLINE value_type operator-=(difference_type v) BOOST_NOEXCEPT
+    {
+        return sub(v);
+    }
+
+    BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
+
+private:
+    BOOST_FORCEINLINE void clear_padding_bits(atomics::detail::false_type) const BOOST_NOEXCEPT
+    {
+    }
+
+    BOOST_FORCEINLINE void clear_padding_bits(atomics::detail::true_type) const BOOST_NOEXCEPT
+    {
+        storage_type old_value = operations::load(this->storage(), boost::memory_order_relaxed);
+        while (true)
+        {
+            storage_type new_value = old_value;
+            atomics::detail::clear_tail_padding_bits< atomics::detail::value_sizeof< value_type >::value >(new_value);
+            bool res = operations::compare_exchange_weak(this->storage(), old_value, new_value, boost::memory_order_relaxed, boost::memory_order_relaxed);
+            if (BOOST_LIKELY(res))
+                break;
+        }
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
+    {
+        storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
+        const bool res = operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
+        expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
+        return res;
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
+    {
+        storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
+        const bool res = operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
+        expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
+        return res;
+    }
+};
+
+#endif // !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
+
+
+//! Implementation for pointers to object types
+template< typename T >
+class base_atomic_ref< T*, void* > :
+    public base_atomic_ref_common< T*, false >
+{
+private:
+    typedef base_atomic_ref_common< T*, false > base_type;
+
+public:
+    typedef typename base_type::value_type value_type;
+    typedef std::ptrdiff_t difference_type;
+
+protected:
+    typedef typename base_type::operations operations;
+    typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations;
+    typedef typename base_type::storage_type storage_type;
+    typedef value_type value_arg_type;
+
+private:
+    typedef atomics::detail::integral_constant< bool, atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment > use_bitwise_cast;
+
+    // uintptr_storage_type is the minimal storage type that is enough to store pointers. The actual storage_type theoretically may be larger,
+    // if the target architecture only supports atomic ops on larger data. Typically, though, they are the same type.
+    typedef atomics::detail::uintptr_t uintptr_storage_type;
+
+public:
+    BOOST_DEFAULTED_FUNCTION(base_atomic_ref(base_atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
+    BOOST_FORCEINLINE explicit base_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
+    {
+    }
+
+    // Standard methods
+    BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_consume);
+        BOOST_ASSERT(order != memory_order_acquire);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        operations::store(this->storage(), atomics::detail::bitwise_cast< uintptr_storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_release);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::load(this->storage(), order)));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::fetch_add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::fetch_sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
+    }
+
+    BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::exchange(this->storage(), atomics::detail::bitwise_cast< uintptr_storage_type >(v), order)));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    // Boost.Atomic extensions
+    BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(extra_operations::add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
+    }
+
+    BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(extra_operations::sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
+    }
+
+    BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
+    }
+
+    BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
+    }
+
+    BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return extra_operations::add_and_test(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
+    }
+
+    BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
+    {
+        return extra_operations::sub_and_test(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
+    }
+
+    // Operators
+    BOOST_FORCEINLINE value_type operator++(int) BOOST_NOEXCEPT
+    {
+        return fetch_add(1);
+    }
+
+    BOOST_FORCEINLINE value_type operator++() BOOST_NOEXCEPT
+    {
+        return add(1);
+    }
+
+    BOOST_FORCEINLINE value_type operator--(int) BOOST_NOEXCEPT
+    {
+        return fetch_sub(1);
+    }
+
+    BOOST_FORCEINLINE value_type operator--() BOOST_NOEXCEPT
+    {
+        return sub(1);
+    }
+
+    BOOST_FORCEINLINE value_type operator+=(difference_type v) BOOST_NOEXCEPT
+    {
+        return add(v);
+    }
+
+    BOOST_FORCEINLINE value_type operator-=(difference_type v) BOOST_NOEXCEPT
+    {
+        return sub(v);
+    }
+
+    BOOST_DELETED_FUNCTION(base_atomic_ref& operator=(base_atomic_ref const&))
+
+private:
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
+    {
+        storage_type old_value = atomics::detail::bitwise_cast< uintptr_storage_type >(expected);
+        const bool res = operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
+        expected = atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(old_value));
+        return res;
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) const BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) const BOOST_NOEXCEPT
+    {
+        storage_type old_value = atomics::detail::bitwise_cast< uintptr_storage_type >(expected);
+        const bool res = operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
+        expected = atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(old_value));
+        return res;
+    }
+};
+
+} // namespace detail
+
+template< typename T >
+class atomic_ref :
+    public atomics::detail::base_atomic_ref< T, typename atomics::detail::classify< T >::type >
+{
+private:
+    typedef atomics::detail::base_atomic_ref< T, typename atomics::detail::classify< T >::type > base_type;
+    typedef typename base_type::value_arg_type value_arg_type;
+
+public:
+    typedef typename base_type::value_type value_type;
+
+    BOOST_STATIC_ASSERT_MSG(sizeof(value_type) > 0u, "boost::atomic_ref<T> requires T to be a complete type");
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_IS_TRIVIALLY_COPYABLE)
+    BOOST_STATIC_ASSERT_MSG(atomics::detail::is_trivially_copyable< value_type >::value, "boost::atomic_ref<T> requires T to be a trivially copyable type");
+#endif
+
+private:
+    typedef typename base_type::storage_type storage_type;
+
+public:
+    BOOST_DEFAULTED_FUNCTION(atomic_ref(atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
+    BOOST_FORCEINLINE explicit atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
+    {
+        // Check that referenced object alignment satisfies required alignment
+        BOOST_ASSERT((((atomics::detail::uintptr_t)this->m_value) & (base_type::required_alignment - 1u)) == 0u);
+    }
+
+    BOOST_FORCEINLINE value_type operator= (value_arg_type v) BOOST_NOEXCEPT
+    {
+        this->store(v);
+        return v;
+    }
+
+    BOOST_FORCEINLINE operator value_type() const BOOST_NOEXCEPT
+    {
+        return this->load();
+    }
+
+    BOOST_FORCEINLINE bool is_lock_free() const BOOST_NOEXCEPT
+    {
+        // C++20 specifies that is_lock_free returns true if operations on *all* objects of the atomic_ref<T> type are lock-free.
+        // This does not allow to return true or false depending on the referenced object runtime alignment. Currently, Boost.Atomic
+        // follows this specification, although we may support runtime alignment checking in the future.
+        return base_type::is_always_lock_free;
+    }
+
+    BOOST_FORCEINLINE value_type& value() const BOOST_NOEXCEPT { return *this->m_value; }
+
+    BOOST_DELETED_FUNCTION(atomic_ref& operator= (atomic_ref const&))
+};
+
+} // namespace atomics
+} // namespace boost
+
+#if defined(BOOST_MSVC)
+#pragma warning(pop)
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_ATOMIC_REF_TEMPLATE_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/atomic_template.hpp b/ThirdParty/boost/atomic/detail/atomic_template.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..651189284db92ef9f15025ae708f0250837fad89
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/atomic_template.hpp
@@ -0,0 +1,1224 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2011 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2014-2020 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/atomic_template.hpp
+ *
+ * This header contains interface definition of \c atomic template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_ATOMIC_TEMPLATE_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_ATOMIC_TEMPLATE_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/cstdint.hpp>
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/intptr.hpp>
+#include <boost/atomic/detail/classify.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/bitwise_cast.hpp>
+#include <boost/atomic/detail/integral_conversions.hpp>
+#include <boost/atomic/detail/operations.hpp>
+#include <boost/atomic/detail/extra_operations.hpp>
+#include <boost/atomic/detail/memory_order_utils.hpp>
+#include <boost/atomic/detail/type_traits/is_signed.hpp>
+#include <boost/atomic/detail/type_traits/is_trivially_copyable.hpp>
+#include <boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp>
+#include <boost/atomic/detail/type_traits/alignment_of.hpp>
+#include <boost/atomic/detail/type_traits/conditional.hpp>
+#include <boost/atomic/detail/type_traits/integral_constant.hpp>
+#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
+#include <boost/atomic/detail/bitwise_fp_cast.hpp>
+#include <boost/atomic/detail/fp_operations.hpp>
+#include <boost/atomic/detail/extra_fp_operations.hpp>
+#endif
+#if defined(BOOST_ATOMIC_DETAIL_NO_CXX11_ALIGNAS)
+#include <boost/type_traits/type_with_alignment.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(BOOST_MSVC)
+#pragma warning(push)
+// 'boost::atomics::atomic<T>' : multiple assignment operators specified
+#pragma warning(disable: 4522)
+#endif
+
+/*
+ * IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE,
+ *                      see comment for convert_memory_order_to_gcc in ops_gcc_atomic.hpp.
+ */
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< typename T, bool IsSigned >
+class base_atomic_common
+{
+public:
+    typedef T value_type;
+
+protected:
+    typedef atomics::detail::operations< storage_size_of< value_type >::value, IsSigned > operations;
+    typedef typename atomics::detail::conditional< sizeof(value_type) <= sizeof(void*), value_type, value_type const& >::type value_arg_type;
+    typedef typename operations::storage_type storage_type;
+
+protected:
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment ? operations::storage_alignment : atomics::detail::alignment_of< value_type >::value;
+
+protected:
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_ALIGNAS)
+    alignas(storage_alignment) storage_type m_storage;
+#else
+    // Note: Some compilers cannot use constant expressions in alignment attributes, so we have to use the union trick
+    union
+    {
+        storage_type m_storage;
+        typename boost::type_with_alignment< storage_alignment >::type m_aligner;
+    };
+#endif
+
+public:
+    BOOST_DEFAULTED_FUNCTION(base_atomic_common() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
+    BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT explicit base_atomic_common(storage_type v) BOOST_NOEXCEPT : m_storage(v)
+    {
+    }
+
+    BOOST_FORCEINLINE value_type& value() BOOST_NOEXCEPT { return *reinterpret_cast< value_type* >(&m_storage); }
+    BOOST_FORCEINLINE value_type volatile& value() volatile BOOST_NOEXCEPT { return *reinterpret_cast< volatile value_type* >(&m_storage); }
+    BOOST_FORCEINLINE value_type const& value() const BOOST_NOEXCEPT { return *reinterpret_cast< const value_type* >(&m_storage); }
+    BOOST_FORCEINLINE value_type const volatile& value() const volatile BOOST_NOEXCEPT { return *reinterpret_cast< const volatile value_type* >(&m_storage); }
+
+protected:
+    BOOST_FORCEINLINE storage_type& storage() BOOST_NOEXCEPT { return m_storage; }
+    BOOST_FORCEINLINE storage_type volatile& storage() volatile BOOST_NOEXCEPT { return m_storage; }
+    BOOST_FORCEINLINE storage_type const& storage() const BOOST_NOEXCEPT { return m_storage; }
+    BOOST_FORCEINLINE storage_type const volatile& storage() const volatile BOOST_NOEXCEPT { return m_storage; }
+};
+
+
+template< typename T, bool IsTriviallyDefaultConstructible = atomics::detail::is_trivially_default_constructible< T >::value >
+class base_atomic_generic;
+
+template< typename T >
+class base_atomic_generic< T, true > :
+    public base_atomic_common< T, false >
+{
+private:
+    typedef base_atomic_common< T, false > base_type;
+
+protected:
+    typedef typename base_type::storage_type storage_type;
+    typedef typename base_type::value_arg_type value_arg_type;
+
+public:
+    BOOST_DEFAULTED_FUNCTION(base_atomic_generic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
+    BOOST_FORCEINLINE explicit base_atomic_generic(value_arg_type v) BOOST_NOEXCEPT : base_type(atomics::detail::bitwise_cast< storage_type >(v))
+    {
+    }
+};
+
+template< typename T >
+class base_atomic_generic< T, false > :
+    public base_atomic_common< T, false >
+{
+private:
+    typedef base_atomic_common< T, false > base_type;
+
+public:
+    typedef typename base_type::value_type value_type;
+
+protected:
+    typedef typename base_type::storage_type storage_type;
+    typedef typename base_type::value_arg_type value_arg_type;
+
+public:
+    BOOST_FORCEINLINE explicit base_atomic_generic(value_arg_type v = value_type()) BOOST_NOEXCEPT : base_type(atomics::detail::bitwise_cast< storage_type >(v))
+    {
+    }
+};
+
+
+template< typename T, typename Kind >
+class base_atomic;
+
+//! General template. Implementation for user-defined types, such as structs and enums, and pointers to non-object types
+template< typename T >
+class base_atomic< T, void > :
+    public base_atomic_generic< T >
+{
+private:
+    typedef base_atomic_generic< T > base_type;
+
+public:
+    typedef typename base_type::value_type value_type;
+
+protected:
+    typedef typename base_type::operations operations;
+    typedef typename base_type::storage_type storage_type;
+    typedef typename base_type::value_arg_type value_arg_type;
+
+private:
+    typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment > use_bitwise_cast;
+
+public:
+    BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
+    BOOST_FORCEINLINE explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(v)
+    {
+    }
+
+    BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_consume);
+        BOOST_ASSERT(order != memory_order_acquire);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        operations::store(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_release);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        return atomics::detail::bitwise_cast< value_type >(operations::load(this->storage(), order));
+    }
+
+    BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::bitwise_cast< value_type >(operations::exchange(this->storage(), atomics::detail::bitwise_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
+    BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
+
+private:
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
+    {
+        storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
+        const bool res = operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
+        expected = atomics::detail::bitwise_cast< value_type >(old_value);
+        return res;
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
+    {
+        storage_type old_value = atomics::detail::bitwise_cast< storage_type >(expected);
+        const bool res = operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_cast< storage_type >(desired), success_order, failure_order);
+        expected = atomics::detail::bitwise_cast< value_type >(old_value);
+        return res;
+    }
+};
+
+
+//! Implementation for integers
+template< typename T >
+class base_atomic< T, int > :
+    public base_atomic_common< T, atomics::detail::is_signed< T >::value >
+{
+private:
+    typedef base_atomic_common< T, atomics::detail::is_signed< T >::value > base_type;
+
+public:
+    typedef typename base_type::value_type value_type;
+    typedef value_type difference_type;
+
+protected:
+    typedef typename base_type::operations operations;
+    typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations;
+    typedef typename base_type::storage_type storage_type;
+    typedef value_type value_arg_type;
+
+private:
+    typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment > use_bitwise_cast;
+
+public:
+    BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
+    BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(static_cast< storage_type >(v)) {}
+
+    // Standard methods
+    BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_consume);
+        BOOST_ASSERT(order != memory_order_acquire);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        operations::store(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_release);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        return atomics::detail::integral_truncate< value_type >(operations::load(this->storage(), order));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(operations::fetch_add(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(operations::fetch_sub(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(operations::exchange(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_and(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(operations::fetch_and(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_or(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(operations::fetch_or(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_xor(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(operations::fetch_xor(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    // Boost.Atomic extensions
+    BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::fetch_negate(this->storage(), order));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_complement(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::fetch_complement(this->storage(), order));
+    }
+
+    BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::add(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::sub(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::negate(this->storage(), order));
+    }
+
+    BOOST_FORCEINLINE value_type bitwise_and(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_and(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type bitwise_or(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_or(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type bitwise_xor(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_xor(this->storage(), static_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE value_type bitwise_complement(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::integral_truncate< value_type >(extra_operations::bitwise_complement(this->storage(), order));
+    }
+
+    BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_add(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_sub(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_negate(this->storage(), order);
+    }
+
+    BOOST_FORCEINLINE void opaque_and(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_and(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE void opaque_or(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_or(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE void opaque_xor(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_xor(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE void opaque_complement(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_complement(this->storage(), order);
+    }
+
+    BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return extra_operations::add_and_test(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return extra_operations::sub_and_test(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE bool negate_and_test(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return extra_operations::negate_and_test(this->storage(), order);
+    }
+
+    BOOST_FORCEINLINE bool and_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return extra_operations::and_and_test(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE bool or_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return extra_operations::or_and_test(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE bool xor_and_test(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return extra_operations::xor_and_test(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE bool complement_and_test(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return extra_operations::complement_and_test(this->storage(), order);
+    }
+
+    BOOST_FORCEINLINE bool bit_test_and_set(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
+        return extra_operations::bit_test_and_set(this->storage(), bit_number, order);
+    }
+
+    BOOST_FORCEINLINE bool bit_test_and_reset(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
+        return extra_operations::bit_test_and_reset(this->storage(), bit_number, order);
+    }
+
+    BOOST_FORCEINLINE bool bit_test_and_complement(unsigned int bit_number, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(bit_number < sizeof(value_type) * 8u);
+        return extra_operations::bit_test_and_complement(this->storage(), bit_number, order);
+    }
+
+    // Operators
+    BOOST_FORCEINLINE value_type operator++(int) volatile BOOST_NOEXCEPT
+    {
+        return fetch_add(1);
+    }
+
+    BOOST_FORCEINLINE value_type operator++() volatile BOOST_NOEXCEPT
+    {
+        return add(1);
+    }
+
+    BOOST_FORCEINLINE value_type operator--(int) volatile BOOST_NOEXCEPT
+    {
+        return fetch_sub(1);
+    }
+
+    BOOST_FORCEINLINE value_type operator--() volatile BOOST_NOEXCEPT
+    {
+        return sub(1);
+    }
+
+    BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT
+    {
+        return add(v);
+    }
+
+    BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT
+    {
+        return sub(v);
+    }
+
+    BOOST_FORCEINLINE value_type operator&=(value_type v) volatile BOOST_NOEXCEPT
+    {
+        return bitwise_and(v);
+    }
+
+    BOOST_FORCEINLINE value_type operator|=(value_type v) volatile BOOST_NOEXCEPT
+    {
+        return bitwise_or(v);
+    }
+
+    BOOST_FORCEINLINE value_type operator^=(value_type v) volatile BOOST_NOEXCEPT
+    {
+        return bitwise_xor(v);
+    }
+
+    BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
+    BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
+
+private:
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
+    {
+        storage_type old_value = static_cast< storage_type >(expected);
+        const bool res = operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
+        expected = atomics::detail::integral_truncate< value_type >(old_value);
+        return res;
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
+    {
+        storage_type old_value = static_cast< storage_type >(expected);
+        const bool res = operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
+        expected = atomics::detail::integral_truncate< value_type >(old_value);
+        return res;
+    }
+};
+
+//! Implementation for bool
+template< >
+class base_atomic< bool, int > :
+    public base_atomic_common< bool, false >
+{
+private:
+    typedef base_atomic_common< bool, false > base_type;
+
+public:
+    typedef base_type::value_type value_type;
+
+protected:
+    typedef base_type::operations operations;
+    typedef base_type::storage_type storage_type;
+    typedef value_type value_arg_type;
+
+private:
+    typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment > use_bitwise_cast;
+
+public:
+    BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
+    BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(static_cast< storage_type >(v)) {}
+
+    // Standard methods
+    BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_consume);
+        BOOST_ASSERT(order != memory_order_acquire);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        operations::store(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_release);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        return !!operations::load(this->storage(), order);
+    }
+
+    BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return !!operations::exchange(this->storage(), static_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
+    BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
+
+private:
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
+    {
+        storage_type old_value = static_cast< storage_type >(expected);
+        const bool res = operations::compare_exchange_strong(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
+        expected = !!old_value;
+        return res;
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), static_cast< storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
+    {
+        storage_type old_value = static_cast< storage_type >(expected);
+        const bool res = operations::compare_exchange_weak(this->storage(), old_value, static_cast< storage_type >(desired), success_order, failure_order);
+        expected = !!old_value;
+        return res;
+    }
+};
+
+
+#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
+
+//! Implementation for floating point types
+template< typename T >
+class base_atomic< T, float > :
+    public base_atomic_common< T, false >
+{
+private:
+    typedef base_atomic_common< T, false > base_type;
+
+public:
+    typedef typename base_type::value_type value_type;
+    typedef value_type difference_type;
+
+protected:
+    typedef typename base_type::operations operations;
+    typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations;
+    typedef atomics::detail::fp_operations< extra_operations, value_type, operations::storage_size > fp_operations;
+    typedef atomics::detail::extra_fp_operations< fp_operations, value_type, operations::storage_size > extra_fp_operations;
+    typedef typename base_type::storage_type storage_type;
+    typedef value_type value_arg_type;
+
+private:
+    typedef atomics::detail::integral_constant< bool,
+        atomics::detail::value_sizeof< value_type >::value != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment
+    > use_bitwise_cast;
+
+public:
+    BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
+    BOOST_FORCEINLINE explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(atomics::detail::bitwise_fp_cast< storage_type >(v)) {}
+
+    BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_consume);
+        BOOST_ASSERT(order != memory_order_acquire);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        operations::store(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_release);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        return atomics::detail::bitwise_fp_cast< value_type >(operations::load(this->storage(), order));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return fp_operations::fetch_add(this->storage(), v, order);
+    }
+
+    BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return fp_operations::fetch_sub(this->storage(), v, order);
+    }
+
+    BOOST_FORCEINLINE value_type exchange(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::bitwise_fp_cast< value_type >(operations::exchange(this->storage(), atomics::detail::bitwise_fp_cast< storage_type >(v), order));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    // Boost.Atomic extensions
+    BOOST_FORCEINLINE value_type fetch_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return extra_fp_operations::fetch_negate(this->storage(), order);
+    }
+
+    BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return extra_fp_operations::add(this->storage(), v, order);
+    }
+
+    BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return extra_fp_operations::sub(this->storage(), v, order);
+    }
+
+    BOOST_FORCEINLINE value_type negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return extra_fp_operations::negate(this->storage(), order);
+    }
+
+    BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        extra_fp_operations::opaque_add(this->storage(), v, order);
+    }
+
+    BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        extra_fp_operations::opaque_sub(this->storage(), v, order);
+    }
+
+    BOOST_FORCEINLINE void opaque_negate(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        extra_fp_operations::opaque_negate(this->storage(), order);
+    }
+
+    // Operators
+    BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT
+    {
+        return add(v);
+    }
+
+    BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT
+    {
+        return sub(v);
+    }
+
+    BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
+    BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
+
+private:
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
+    {
+        storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
+        const bool res = operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
+        expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
+        return res;
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
+    {
+        storage_type old_value = atomics::detail::bitwise_fp_cast< storage_type >(expected);
+        const bool res = operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_fp_cast< storage_type >(desired), success_order, failure_order);
+        expected = atomics::detail::bitwise_fp_cast< value_type >(old_value);
+        return res;
+    }
+};
+
+#endif // !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
+
+
+//! Implementation for pointers to object types
+template< typename T >
+class base_atomic< T*, void* > :
+    public base_atomic_common< T*, false >
+{
+private:
+    typedef base_atomic_common< T*, false > base_type;
+
+public:
+    typedef typename base_type::value_type value_type;
+    typedef std::ptrdiff_t difference_type;
+
+protected:
+    typedef typename base_type::operations operations;
+    typedef atomics::detail::extra_operations< operations, operations::storage_size, operations::is_signed > extra_operations;
+    typedef typename base_type::storage_type storage_type;
+    typedef value_type value_arg_type;
+
+private:
+    typedef atomics::detail::integral_constant< bool, sizeof(value_type) != sizeof(storage_type) || atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment > use_bitwise_cast;
+
+    // uintptr_storage_type is the minimal storage type that is enough to store pointers. The actual storage_type theoretically may be larger,
+    // if the target architecture only supports atomic ops on larger data. Typically, though, they are the same type.
+    typedef atomics::detail::uintptr_t uintptr_storage_type;
+
+public:
+    BOOST_DEFAULTED_FUNCTION(base_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
+    BOOST_FORCEINLINE explicit base_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(atomics::detail::bitwise_cast< uintptr_storage_type >(v))
+    {
+    }
+
+    // Standard methods
+    BOOST_FORCEINLINE void store(value_arg_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_consume);
+        BOOST_ASSERT(order != memory_order_acquire);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        operations::store(this->storage(), atomics::detail::bitwise_cast< uintptr_storage_type >(v), order);
+    }
+
+    BOOST_FORCEINLINE value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(order != memory_order_release);
+        BOOST_ASSERT(order != memory_order_acq_rel);
+
+        return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::load(this->storage(), order)));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::fetch_add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
+    }
+
+    BOOST_FORCEINLINE value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::fetch_sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
+    }
+
+    BOOST_FORCEINLINE value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(operations::exchange(this->storage(), atomics::detail::bitwise_cast< uintptr_storage_type >(v), order)));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
+    {
+        BOOST_ASSERT(failure_order != memory_order_release);
+        BOOST_ASSERT(failure_order != memory_order_acq_rel);
+        BOOST_ASSERT(cas_failure_order_must_not_be_stronger_than_success_order(success_order, failure_order));
+
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, use_bitwise_cast());
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak(value_type& expected, value_arg_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
+    }
+
+    // Boost.Atomic extensions
+    BOOST_FORCEINLINE value_type add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(extra_operations::add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
+    }
+
+    BOOST_FORCEINLINE value_type sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(extra_operations::sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order)));
+    }
+
+    BOOST_FORCEINLINE void opaque_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_add(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
+    }
+
+    BOOST_FORCEINLINE void opaque_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        extra_operations::opaque_sub(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
+    }
+
+    BOOST_FORCEINLINE bool add_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return extra_operations::add_and_test(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
+    }
+
+    BOOST_FORCEINLINE bool sub_and_test(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
+    {
+        return extra_operations::sub_and_test(this->storage(), static_cast< uintptr_storage_type >(v * sizeof(T)), order);
+    }
+
+    // Operators
+    BOOST_FORCEINLINE value_type operator++(int) volatile BOOST_NOEXCEPT
+    {
+        return fetch_add(1);
+    }
+
+    BOOST_FORCEINLINE value_type operator++() volatile BOOST_NOEXCEPT
+    {
+        return add(1);
+    }
+
+    BOOST_FORCEINLINE value_type operator--(int) volatile BOOST_NOEXCEPT
+    {
+        return fetch_sub(1);
+    }
+
+    BOOST_FORCEINLINE value_type operator--() volatile BOOST_NOEXCEPT
+    {
+        return sub(1);
+    }
+
+    BOOST_FORCEINLINE value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT
+    {
+        return add(v);
+    }
+
+    BOOST_FORCEINLINE value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT
+    {
+        return sub(v);
+    }
+
+    BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
+    BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
+
+private:
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_strong(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_strong_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_strong_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
+    {
+        storage_type old_value = atomics::detail::bitwise_cast< uintptr_storage_type >(expected);
+        const bool res = operations::compare_exchange_strong(this->storage(), old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
+        expected = atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(old_value));
+        return res;
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::false_type) volatile BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS)
+        return operations::compare_exchange_weak(this->storage(), reinterpret_cast< storage_type& >(expected), atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
+#else
+        return compare_exchange_weak_impl(expected, desired, success_order, failure_order, atomics::detail::true_type());
+#endif
+    }
+
+    BOOST_FORCEINLINE bool compare_exchange_weak_impl(value_type& expected, value_arg_type desired, memory_order success_order, memory_order failure_order, atomics::detail::true_type) volatile BOOST_NOEXCEPT
+    {
+        storage_type old_value = atomics::detail::bitwise_cast< uintptr_storage_type >(expected);
+        const bool res = operations::compare_exchange_weak(this->storage(), old_value, atomics::detail::bitwise_cast< uintptr_storage_type >(desired), success_order, failure_order);
+        expected = atomics::detail::bitwise_cast< value_type >(static_cast< uintptr_storage_type >(old_value));
+        return res;
+    }
+};
+
+} // namespace detail
+
+template< typename T >
+class atomic :
+    public atomics::detail::base_atomic< T, typename atomics::detail::classify< T >::type >
+{
+private:
+    typedef atomics::detail::base_atomic< T, typename atomics::detail::classify< T >::type > base_type;
+    typedef typename base_type::value_arg_type value_arg_type;
+
+public:
+    typedef typename base_type::value_type value_type;
+    // Deprecated, use value_type instead
+    BOOST_ATOMIC_DETAIL_STORAGE_DEPRECATED
+    typedef typename base_type::storage_type storage_type;
+
+    BOOST_STATIC_ASSERT_MSG(sizeof(value_type) > 0u, "boost::atomic<T> requires T to be a complete type");
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_IS_TRIVIALLY_COPYABLE)
+    BOOST_STATIC_ASSERT_MSG(atomics::detail::is_trivially_copyable< value_type >::value, "boost::atomic<T> requires T to be a trivially copyable type");
+#endif
+
+public:
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = base_type::operations::is_always_lock_free;
+
+public:
+    BOOST_DEFAULTED_FUNCTION(atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
+    BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(v) {}
+
+    BOOST_FORCEINLINE value_type operator= (value_arg_type v) BOOST_NOEXCEPT
+    {
+        this->store(v);
+        return v;
+    }
+
+    BOOST_FORCEINLINE value_type operator= (value_arg_type v) volatile BOOST_NOEXCEPT
+    {
+        this->store(v);
+        return v;
+    }
+
+    BOOST_FORCEINLINE operator value_type() const volatile BOOST_NOEXCEPT
+    {
+        return this->load();
+    }
+
+    BOOST_FORCEINLINE bool is_lock_free() const volatile BOOST_NOEXCEPT
+    {
+        // C++17 requires all instances of atomic<> return a value consistent with is_always_lock_free here
+        return is_always_lock_free;
+    }
+
+    // Deprecated, use value() instead
+    BOOST_ATOMIC_DETAIL_STORAGE_DEPRECATED
+    BOOST_FORCEINLINE typename base_type::storage_type& storage() BOOST_NOEXCEPT { return base_type::storage(); }
+    BOOST_ATOMIC_DETAIL_STORAGE_DEPRECATED
+    BOOST_FORCEINLINE typename base_type::storage_type volatile& storage() volatile BOOST_NOEXCEPT { return base_type::storage(); }
+    BOOST_ATOMIC_DETAIL_STORAGE_DEPRECATED
+    BOOST_FORCEINLINE typename base_type::storage_type const& storage() const BOOST_NOEXCEPT { return base_type::storage(); }
+    BOOST_ATOMIC_DETAIL_STORAGE_DEPRECATED
+    BOOST_FORCEINLINE typename base_type::storage_type const volatile& storage() const volatile BOOST_NOEXCEPT { return base_type::storage(); }
+
+    BOOST_DELETED_FUNCTION(atomic(atomic const&))
+    BOOST_DELETED_FUNCTION(atomic& operator= (atomic const&))
+    BOOST_DELETED_FUNCTION(atomic& operator= (atomic const&) volatile)
+};
+
+#if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
+template< typename T >
+BOOST_CONSTEXPR_OR_CONST bool atomic< T >::is_always_lock_free;
+#endif
+
+typedef atomic< char > atomic_char;
+typedef atomic< unsigned char > atomic_uchar;
+typedef atomic< signed char > atomic_schar;
+typedef atomic< uint8_t > atomic_uint8_t;
+typedef atomic< int8_t > atomic_int8_t;
+typedef atomic< unsigned short > atomic_ushort;
+typedef atomic< short > atomic_short;
+typedef atomic< uint16_t > atomic_uint16_t;
+typedef atomic< int16_t > atomic_int16_t;
+typedef atomic< unsigned int > atomic_uint;
+typedef atomic< int > atomic_int;
+typedef atomic< uint32_t > atomic_uint32_t;
+typedef atomic< int32_t > atomic_int32_t;
+typedef atomic< unsigned long > atomic_ulong;
+typedef atomic< long > atomic_long;
+typedef atomic< uint64_t > atomic_uint64_t;
+typedef atomic< int64_t > atomic_int64_t;
+#ifdef BOOST_HAS_LONG_LONG
+typedef atomic< boost::ulong_long_type > atomic_ullong;
+typedef atomic< boost::long_long_type > atomic_llong;
+#endif
+typedef atomic< void* > atomic_address;
+typedef atomic< bool > atomic_bool;
+typedef atomic< wchar_t > atomic_wchar_t;
+#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811
+typedef atomic< char8_t > atomic_char8_t;
+#endif
+#if !defined(BOOST_NO_CXX11_CHAR16_T)
+typedef atomic< char16_t > atomic_char16_t;
+#endif
+#if !defined(BOOST_NO_CXX11_CHAR32_T)
+typedef atomic< char32_t > atomic_char32_t;
+#endif
+
+typedef atomic< int_least8_t > atomic_int_least8_t;
+typedef atomic< uint_least8_t > atomic_uint_least8_t;
+typedef atomic< int_least16_t > atomic_int_least16_t;
+typedef atomic< uint_least16_t > atomic_uint_least16_t;
+typedef atomic< int_least32_t > atomic_int_least32_t;
+typedef atomic< uint_least32_t > atomic_uint_least32_t;
+typedef atomic< int_least64_t > atomic_int_least64_t;
+typedef atomic< uint_least64_t > atomic_uint_least64_t;
+typedef atomic< int_fast8_t > atomic_int_fast8_t;
+typedef atomic< uint_fast8_t > atomic_uint_fast8_t;
+typedef atomic< int_fast16_t > atomic_int_fast16_t;
+typedef atomic< uint_fast16_t > atomic_uint_fast16_t;
+typedef atomic< int_fast32_t > atomic_int_fast32_t;
+typedef atomic< uint_fast32_t > atomic_uint_fast32_t;
+typedef atomic< int_fast64_t > atomic_int_fast64_t;
+typedef atomic< uint_fast64_t > atomic_uint_fast64_t;
+typedef atomic< intmax_t > atomic_intmax_t;
+typedef atomic< uintmax_t > atomic_uintmax_t;
+
+#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
+typedef atomic< float > atomic_float_t;
+typedef atomic< double > atomic_double_t;
+typedef atomic< long double > atomic_long_double_t;
+#endif
+
+typedef atomic< std::size_t > atomic_size_t;
+typedef atomic< std::ptrdiff_t > atomic_ptrdiff_t;
+
+#if defined(BOOST_HAS_INTPTR_T)
+typedef atomic< boost::intptr_t > atomic_intptr_t;
+typedef atomic< boost::uintptr_t > atomic_uintptr_t;
+#endif
+
+} // namespace atomics
+} // namespace boost
+
+#if defined(BOOST_MSVC)
+#pragma warning(pop)
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_ATOMIC_TEMPLATE_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/bitwise_cast.hpp b/ThirdParty/boost/atomic/detail/bitwise_cast.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..949a1e50b81648279e064114ef6807b445d5dfea
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/bitwise_cast.hpp
@@ -0,0 +1,84 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2012 Tim Blechmann
+ * Copyright (c) 2013 - 2018, 2020 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/bitwise_cast.hpp
+ *
+ * This header defines \c bitwise_cast used to convert between storage and value types
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_BITWISE_CAST_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_BITWISE_CAST_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/addressof.hpp>
+#include <boost/atomic/detail/string_ops.hpp>
+#include <boost/atomic/detail/type_traits/integral_constant.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(BOOST_GCC) && BOOST_GCC >= 80000
+#pragma GCC diagnostic push
+// copying an object of non-trivial type X from an array of Y. This is benign because we use memcpy to copy trivially copyable objects.
+#pragma GCC diagnostic ignored "-Wclass-memaccess"
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< std::size_t FromSize, typename To >
+BOOST_FORCEINLINE void clear_tail_padding_bits(To& to, atomics::detail::true_type) BOOST_NOEXCEPT
+{
+    BOOST_ATOMIC_DETAIL_MEMSET(reinterpret_cast< unsigned char* >(atomics::detail::addressof(to)) + FromSize, 0, sizeof(To) - FromSize);
+}
+
+template< std::size_t FromSize, typename To >
+BOOST_FORCEINLINE void clear_tail_padding_bits(To&, atomics::detail::false_type) BOOST_NOEXCEPT
+{
+}
+
+template< std::size_t FromSize, typename To >
+BOOST_FORCEINLINE void clear_tail_padding_bits(To& to) BOOST_NOEXCEPT
+{
+    atomics::detail::clear_tail_padding_bits< FromSize >(to, atomics::detail::integral_constant< bool, FromSize < sizeof(To) >());
+}
+
+template< typename To, std::size_t FromSize, typename From >
+BOOST_FORCEINLINE To bitwise_cast(From const& from) BOOST_NOEXCEPT
+{
+    To to;
+    BOOST_ATOMIC_DETAIL_MEMCPY
+    (
+        atomics::detail::addressof(to),
+        atomics::detail::addressof(from),
+        (FromSize < sizeof(To) ? FromSize : sizeof(To))
+    );
+    atomics::detail::clear_tail_padding_bits< FromSize >(to);
+    return to;
+}
+
+template< typename To, typename From >
+BOOST_FORCEINLINE To bitwise_cast(From const& from) BOOST_NOEXCEPT
+{
+    return atomics::detail::bitwise_cast< To, sizeof(From) >(from);
+}
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#if defined(BOOST_GCC) && BOOST_GCC >= 80000
+#pragma GCC diagnostic pop
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_BITWISE_CAST_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/bitwise_fp_cast.hpp b/ThirdParty/boost/atomic/detail/bitwise_fp_cast.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a74b20b9720f22174a373e1c301b8f367404bbd8
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/bitwise_fp_cast.hpp
@@ -0,0 +1,86 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/bitwise_fp_cast.hpp
+ *
+ * This header defines \c bitwise_fp_cast used to convert between storage and floating point value types
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_BITWISE_FP_CAST_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_BITWISE_FP_CAST_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/float_sizes.hpp>
+#include <boost/atomic/detail/bitwise_cast.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+/*!
+ * \brief The type trait returns the size of the value of the specified floating point type
+ *
+ * This size may be less than <tt>sizeof(T)</tt> if the implementation uses padding bytes for a particular FP type. This is
+ * often the case with 80-bit extended double, which is stored in 12 or 16 bytes with padding filled with garbage.
+ */
+template< typename T >
+struct value_sizeof
+{
+    static BOOST_CONSTEXPR_OR_CONST std::size_t value = sizeof(T);
+};
+
+#if defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE)
+template< >
+struct value_sizeof< float >
+{
+    static BOOST_CONSTEXPR_OR_CONST std::size_t value = BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE;
+};
+#endif
+
+#if defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE)
+template< >
+struct value_sizeof< double >
+{
+    static BOOST_CONSTEXPR_OR_CONST std::size_t value = BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE;
+};
+#endif
+
+#if defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE)
+template< >
+struct value_sizeof< long double >
+{
+    static BOOST_CONSTEXPR_OR_CONST std::size_t value = BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE;
+};
+#endif
+
+template< typename T >
+struct value_sizeof< const T > : value_sizeof< T > {};
+
+template< typename T >
+struct value_sizeof< volatile T > : value_sizeof< T > {};
+
+template< typename T >
+struct value_sizeof< const volatile T > : value_sizeof< T > {};
+
+
+template< typename To, typename From >
+BOOST_FORCEINLINE To bitwise_fp_cast(From const& from) BOOST_NOEXCEPT
+{
+    return atomics::detail::bitwise_cast< To, atomics::detail::value_sizeof< From >::value >(from);
+}
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_BITWISE_FP_CAST_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/caps_gcc_alpha.hpp b/ThirdParty/boost/atomic/detail/caps_gcc_alpha.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..861432f58a6922cace478c47b4f7c2461fd7ba68
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/caps_gcc_alpha.hpp
@@ -0,0 +1,34 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/caps_gcc_alpha.hpp
+ *
+ * This header defines feature capabilities macros
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_ALPHA_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_CAPS_GCC_ALPHA_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#define BOOST_ATOMIC_INT8_LOCK_FREE 2
+#define BOOST_ATOMIC_INT16_LOCK_FREE 2
+#define BOOST_ATOMIC_INT32_LOCK_FREE 2
+#define BOOST_ATOMIC_INT64_LOCK_FREE 2
+#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
+
+#define BOOST_ATOMIC_THREAD_FENCE 2
+#define BOOST_ATOMIC_SIGNAL_FENCE 2
+
+#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_ALPHA_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/caps_gcc_arm.hpp b/ThirdParty/boost/atomic/detail/caps_gcc_arm.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a26ea56ee513460a55da866845e8c0d8fd5e00bf
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/caps_gcc_arm.hpp
@@ -0,0 +1,39 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2009 Phil Endecott
+ * Copyright (c) 2013 Tim Blechmann
+ * ARM Code by Phil Endecott, based on other architectures.
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/caps_gcc_arm.hpp
+ *
+ * This header defines feature capabilities macros
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_ARM_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_CAPS_GCC_ARM_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/hwcaps_gcc_arm.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#define BOOST_ATOMIC_INT8_LOCK_FREE 2
+#define BOOST_ATOMIC_INT16_LOCK_FREE 2
+#define BOOST_ATOMIC_INT32_LOCK_FREE 2
+#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD)
+#define BOOST_ATOMIC_INT64_LOCK_FREE 2
+#endif
+#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
+
+#define BOOST_ATOMIC_THREAD_FENCE 2
+#define BOOST_ATOMIC_SIGNAL_FENCE 2
+
+#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_ARM_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/caps_gcc_atomic.hpp b/ThirdParty/boost/atomic/detail/caps_gcc_atomic.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3b518cf49c0f50c7b38c22b54e80d427a4f2d7c9
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/caps_gcc_atomic.hpp
@@ -0,0 +1,133 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/caps_gcc_atomic.hpp
+ *
+ * This header defines feature capabilities macros
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_ATOMIC_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_CAPS_GCC_ATOMIC_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/int_sizes.hpp>
+#if defined(__i386__) || defined(__x86_64__)
+#include <boost/atomic/detail/hwcaps_gcc_x86.hpp>
+#elif defined(__arm__)
+#include <boost/atomic/detail/hwcaps_gcc_arm.hpp>
+#elif defined(__POWERPC__) || defined(__PPC__)
+#include <boost/atomic/detail/hwcaps_gcc_ppc.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) && (defined(BOOST_HAS_INT128) || !defined(BOOST_NO_ALIGNMENT))
+#define BOOST_ATOMIC_INT128_LOCK_FREE 2
+#else
+#define BOOST_ATOMIC_INT128_LOCK_FREE 0
+#endif
+
+#if (__GCC_ATOMIC_LLONG_LOCK_FREE == 2) || (defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) && BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 8)
+#define BOOST_ATOMIC_LLONG_LOCK_FREE 2
+#else
+#define BOOST_ATOMIC_LLONG_LOCK_FREE BOOST_ATOMIC_INT128_LOCK_FREE
+#endif
+
+#if (__GCC_ATOMIC_LONG_LOCK_FREE == 2) || (defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) && BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8)
+#define BOOST_ATOMIC_LONG_LOCK_FREE 2
+#else
+#define BOOST_ATOMIC_LONG_LOCK_FREE BOOST_ATOMIC_LLONG_LOCK_FREE
+#endif
+
+#if __GCC_ATOMIC_INT_LOCK_FREE == 2
+#define BOOST_ATOMIC_INT_LOCK_FREE 2
+#else
+#define BOOST_ATOMIC_INT_LOCK_FREE BOOST_ATOMIC_LONG_LOCK_FREE
+#endif
+
+#if __GCC_ATOMIC_SHORT_LOCK_FREE == 2
+#define BOOST_ATOMIC_SHORT_LOCK_FREE 2
+#else
+#define BOOST_ATOMIC_SHORT_LOCK_FREE BOOST_ATOMIC_INT_LOCK_FREE
+#endif
+
+#if __GCC_ATOMIC_CHAR_LOCK_FREE == 2
+#define BOOST_ATOMIC_CHAR_LOCK_FREE 2
+#else
+#define BOOST_ATOMIC_CHAR_LOCK_FREE BOOST_ATOMIC_SHORT_LOCK_FREE
+#endif
+
+#if __GCC_ATOMIC_POINTER_LOCK_FREE == 2
+#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
+#else
+#define BOOST_ATOMIC_POINTER_LOCK_FREE 0
+#endif
+
+
+#define BOOST_ATOMIC_INT8_LOCK_FREE BOOST_ATOMIC_CHAR_LOCK_FREE
+
+#if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 2
+#define BOOST_ATOMIC_INT16_LOCK_FREE BOOST_ATOMIC_SHORT_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 2
+#define BOOST_ATOMIC_INT16_LOCK_FREE BOOST_ATOMIC_INT_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 2
+#define BOOST_ATOMIC_INT16_LOCK_FREE BOOST_ATOMIC_LONG_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 2
+#define BOOST_ATOMIC_INT16_LOCK_FREE BOOST_ATOMIC_LLONG_LOCK_FREE
+#else
+#define BOOST_ATOMIC_INT16_LOCK_FREE 0
+#endif
+
+#if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 4
+#define BOOST_ATOMIC_INT32_LOCK_FREE BOOST_ATOMIC_SHORT_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 4
+#define BOOST_ATOMIC_INT32_LOCK_FREE BOOST_ATOMIC_INT_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 4
+#define BOOST_ATOMIC_INT32_LOCK_FREE BOOST_ATOMIC_LONG_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 4
+#define BOOST_ATOMIC_INT32_LOCK_FREE BOOST_ATOMIC_LLONG_LOCK_FREE
+#else
+#define BOOST_ATOMIC_INT32_LOCK_FREE 0
+#endif
+
+#if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 8
+#define BOOST_ATOMIC_INT64_LOCK_FREE BOOST_ATOMIC_SHORT_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 8
+#define BOOST_ATOMIC_INT64_LOCK_FREE BOOST_ATOMIC_INT_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8
+#define BOOST_ATOMIC_INT64_LOCK_FREE BOOST_ATOMIC_LONG_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 8
+#define BOOST_ATOMIC_INT64_LOCK_FREE BOOST_ATOMIC_LLONG_LOCK_FREE
+#else
+#define BOOST_ATOMIC_INT64_LOCK_FREE 0
+#endif
+
+
+#if __GCC_ATOMIC_WCHAR_T_LOCK_FREE == 2
+#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 2
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 8
+#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 4
+#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 2
+#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
+#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 1
+#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE BOOST_ATOMIC_INT8_LOCK_FREE
+#else
+#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 0
+#endif
+
+#define BOOST_ATOMIC_CHAR32_T_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
+#define BOOST_ATOMIC_CHAR16_T_LOCK_FREE BOOST_ATOMIC_INT16_LOCK_FREE
+
+#define BOOST_ATOMIC_THREAD_FENCE 2
+#define BOOST_ATOMIC_SIGNAL_FENCE 2
+
+#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_ATOMIC_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/caps_gcc_ppc.hpp b/ThirdParty/boost/atomic/detail/caps_gcc_ppc.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3e20fdee45ae6261792c7dc6b19dd8f9e2108286
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/caps_gcc_ppc.hpp
@@ -0,0 +1,37 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/caps_gcc_ppc.hpp
+ *
+ * This header defines feature capabilities macros
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_PPC_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_CAPS_GCC_PPC_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/hwcaps_gcc_ppc.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#define BOOST_ATOMIC_INT8_LOCK_FREE 2
+#define BOOST_ATOMIC_INT16_LOCK_FREE 2
+#define BOOST_ATOMIC_INT32_LOCK_FREE 2
+#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
+#define BOOST_ATOMIC_INT64_LOCK_FREE 2
+#endif
+#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
+
+#define BOOST_ATOMIC_THREAD_FENCE 2
+#define BOOST_ATOMIC_SIGNAL_FENCE 2
+
+#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_PPC_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/caps_gcc_sparc.hpp b/ThirdParty/boost/atomic/detail/caps_gcc_sparc.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5806684926a958825cc285f871ec5a4162c25a93
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/caps_gcc_sparc.hpp
@@ -0,0 +1,34 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2010 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/caps_gcc_sparc.hpp
+ *
+ * This header defines feature capabilities macros
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_SPARC_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_CAPS_GCC_SPARC_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#define BOOST_ATOMIC_INT8_LOCK_FREE 2
+#define BOOST_ATOMIC_INT16_LOCK_FREE 2
+#define BOOST_ATOMIC_INT32_LOCK_FREE 2
+#define BOOST_ATOMIC_INT64_LOCK_FREE 2
+#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
+
+#define BOOST_ATOMIC_THREAD_FENCE 2
+#define BOOST_ATOMIC_SIGNAL_FENCE 2
+
+#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_SPARC_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/caps_gcc_sync.hpp b/ThirdParty/boost/atomic/detail/caps_gcc_sync.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ffbe605a1a7725b442353052225de6fe169a9c27
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/caps_gcc_sync.hpp
@@ -0,0 +1,61 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2011 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/caps_gcc_sync.hpp
+ *
+ * This header defines feature capabilities macros
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_SYNC_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_CAPS_GCC_SYNC_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+#if defined(__i386__) || defined(__x86_64__)
+#include <boost/atomic/detail/hwcaps_gcc_x86.hpp>
+#elif defined(__arm__)
+#include <boost/atomic/detail/hwcaps_gcc_arm.hpp>
+#elif defined(__POWERPC__) || defined(__PPC__)
+#include <boost/atomic/detail/hwcaps_gcc_ppc.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1)\
+    || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)\
+    || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)\
+    || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\
+    || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
+#define BOOST_ATOMIC_INT8_LOCK_FREE 2
+#endif
+#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)\
+    || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)\
+    || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\
+    || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
+#define BOOST_ATOMIC_INT16_LOCK_FREE 2
+#endif
+#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)\
+    || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\
+    || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
+#define BOOST_ATOMIC_INT32_LOCK_FREE 2
+#endif
+#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\
+    || defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
+#define BOOST_ATOMIC_INT64_LOCK_FREE 2
+#endif
+#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
+#define BOOST_ATOMIC_INT128_LOCK_FREE 2
+#endif
+
+#define BOOST_ATOMIC_THREAD_FENCE 2
+#define BOOST_ATOMIC_SIGNAL_FENCE 2
+
+#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_SYNC_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/caps_gcc_x86.hpp b/ThirdParty/boost/atomic/detail/caps_gcc_x86.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..70c64628afdd3cabff45676d6c2fd78303e30baa
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/caps_gcc_x86.hpp
@@ -0,0 +1,40 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2012 Tim Blechmann
+ * Copyright (c) 2013 - 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/caps_gcc_x86.hpp
+ *
+ * This header defines feature capabilities macros
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_CAPS_GCC_X86_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_CAPS_GCC_X86_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/hwcaps_gcc_x86.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#define BOOST_ATOMIC_INT8_LOCK_FREE 2
+#define BOOST_ATOMIC_INT16_LOCK_FREE 2
+#define BOOST_ATOMIC_INT32_LOCK_FREE 2
+#if defined(__x86_64__) || defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B)
+#define BOOST_ATOMIC_INT64_LOCK_FREE 2
+#endif
+#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) && (defined(BOOST_HAS_INT128) || !defined(BOOST_NO_ALIGNMENT))
+#define BOOST_ATOMIC_INT128_LOCK_FREE 2
+#endif
+#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
+
+#define BOOST_ATOMIC_THREAD_FENCE 2
+#define BOOST_ATOMIC_SIGNAL_FENCE 2
+
+#endif // BOOST_ATOMIC_DETAIL_CAPS_GCC_X86_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/caps_linux_arm.hpp b/ThirdParty/boost/atomic/detail/caps_linux_arm.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..abe6fb81af751fb91e5d0e14eec5f3bc10024c44
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/caps_linux_arm.hpp
@@ -0,0 +1,35 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009, 2011 Helge Bahmann
+ * Copyright (c) 2009 Phil Endecott
+ * Copyright (c) 2013 Tim Blechmann
+ * Linux-specific code by Phil Endecott
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/caps_linux_arm.hpp
+ *
+ * This header defines feature capabilities macros
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_CAPS_LINUX_ARM_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_CAPS_LINUX_ARM_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#define BOOST_ATOMIC_INT8_LOCK_FREE 2
+#define BOOST_ATOMIC_INT16_LOCK_FREE 2
+#define BOOST_ATOMIC_INT32_LOCK_FREE 2
+#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
+
+#define BOOST_ATOMIC_THREAD_FENCE 2
+#define BOOST_ATOMIC_SIGNAL_FENCE 2
+
+#endif // BOOST_ATOMIC_DETAIL_CAPS_LINUX_ARM_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/caps_msvc_arm.hpp b/ThirdParty/boost/atomic/detail/caps_msvc_arm.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6b3c61fb3ee1b685f153ff277a52188bc43c8a20
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/caps_msvc_arm.hpp
@@ -0,0 +1,34 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2012 - 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/caps_msvc_arm.hpp
+ *
+ * This header defines feature capabilities macros
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_CAPS_MSVC_ARM_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_CAPS_MSVC_ARM_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#define BOOST_ATOMIC_INT8_LOCK_FREE 2
+#define BOOST_ATOMIC_INT16_LOCK_FREE 2
+#define BOOST_ATOMIC_INT32_LOCK_FREE 2
+#define BOOST_ATOMIC_INT64_LOCK_FREE 2
+#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
+
+#define BOOST_ATOMIC_THREAD_FENCE 2
+#define BOOST_ATOMIC_SIGNAL_FENCE 2
+
+#endif // BOOST_ATOMIC_DETAIL_CAPS_MSVC_ARM_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/caps_msvc_x86.hpp b/ThirdParty/boost/atomic/detail/caps_msvc_x86.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..07c8451dea2e583ba972357b367a52ae39a2097e
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/caps_msvc_x86.hpp
@@ -0,0 +1,59 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2012 - 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/caps_msvc_x86.hpp
+ *
+ * This header defines feature capabilities macros
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_CAPS_MSVC_X86_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_CAPS_MSVC_X86_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(_M_IX86) && _M_IX86 >= 500
+#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B 1
+#endif
+
+#if !defined(BOOST_ATOMIC_NO_CMPXCHG16B)
+#if defined(__clang__) && (defined(_M_AMD64) || defined(__x86_64__)) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
+#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1
+#elif _MSC_VER >= 1500 && defined(_M_AMD64)
+#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1
+#endif
+#endif
+
+#if defined(_MSC_VER) && (defined(_M_AMD64) || (defined(_M_IX86) && defined(_M_IX86_FP) && _M_IX86_FP >= 2))
+// Use mfence only if SSE2 is available
+#define BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE 1
+#endif
+
+#define BOOST_ATOMIC_INT8_LOCK_FREE 2
+#define BOOST_ATOMIC_INT16_LOCK_FREE 2
+#define BOOST_ATOMIC_INT32_LOCK_FREE 2
+
+#if defined(_M_AMD64) || defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B)
+#define BOOST_ATOMIC_INT64_LOCK_FREE 2
+#endif
+
+#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B) && (defined(BOOST_HAS_INT128) || !defined(BOOST_NO_ALIGNMENT))
+#define BOOST_ATOMIC_INT128_LOCK_FREE 2
+#endif
+
+#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
+
+#define BOOST_ATOMIC_THREAD_FENCE 2
+#define BOOST_ATOMIC_SIGNAL_FENCE 2
+
+#endif // BOOST_ATOMIC_DETAIL_CAPS_MSVC_X86_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/caps_windows.hpp b/ThirdParty/boost/atomic/detail/caps_windows.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1cc0ded83331a80403d81fd2108350b5c5f7a1c9
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/caps_windows.hpp
@@ -0,0 +1,33 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2012 - 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/caps_windows.hpp
+ *
+ * This header defines feature capabilities macros
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_CAPS_WINDOWS_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_CAPS_WINDOWS_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#define BOOST_ATOMIC_INT8_LOCK_FREE 2
+#define BOOST_ATOMIC_INT16_LOCK_FREE 2
+#define BOOST_ATOMIC_INT32_LOCK_FREE 2
+#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
+
+#define BOOST_ATOMIC_THREAD_FENCE 2
+#define BOOST_ATOMIC_SIGNAL_FENCE 2
+
+#endif // BOOST_ATOMIC_DETAIL_CAPS_WINDOWS_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/classify.hpp b/ThirdParty/boost/atomic/detail/classify.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..447a907ab9aad078a4d6d7d12fd6f7c2e132f463
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/classify.hpp
@@ -0,0 +1,78 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2020 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/classify.hpp
+ *
+ * This header contains type traits for type classification.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_CLASSIFY_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_CLASSIFY_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/type_traits/is_integral.hpp>
+#include <boost/atomic/detail/type_traits/is_function.hpp>
+#include <boost/atomic/detail/type_traits/is_floating_point.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< typename T, bool IsFunction = atomics::detail::is_function< T >::value >
+struct classify_pointer
+{
+    typedef void* type;
+};
+
+template< typename T >
+struct classify_pointer< T, true >
+{
+    typedef void type;
+};
+
+template< typename T, bool IsInt = atomics::detail::is_integral< T >::value, bool IsFloat = atomics::detail::is_floating_point< T >::value >
+struct classify
+{
+    typedef void type;
+};
+
+template< typename T >
+struct classify< T, true, false > { typedef int type; };
+
+#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
+template< typename T >
+struct classify< T, false, true > { typedef float type; };
+#endif
+
+template< typename T >
+struct classify< T*, false, false > { typedef typename classify_pointer< T >::type type; };
+
+template< >
+struct classify< void*, false, false > { typedef void type; };
+
+template< >
+struct classify< const void*, false, false > { typedef void type; };
+
+template< >
+struct classify< volatile void*, false, false > { typedef void type; };
+
+template< >
+struct classify< const volatile void*, false, false > { typedef void type; };
+
+template< typename T, typename U >
+struct classify< T U::*, false, false > { typedef void type; };
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_CLASSIFY_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/config.hpp b/ThirdParty/boost/atomic/detail/config.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..64ec59729cff0292d717bfce76aa4a3772676143
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/config.hpp
@@ -0,0 +1,174 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2012 Hartmut Kaiser
+ * Copyright (c) 2014-2018, 2020 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/config.hpp
+ *
+ * This header defines configuraion macros for Boost.Atomic
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_CONFIG_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_CONFIG_HPP_INCLUDED_
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(__CUDACC__)
+// nvcc does not support alternatives ("q,m") in asm statement constraints
+#define BOOST_ATOMIC_DETAIL_NO_ASM_CONSTRAINT_ALTERNATIVES
+// nvcc does not support condition code register ("cc") clobber in asm statements
+#define BOOST_ATOMIC_DETAIL_NO_ASM_CLOBBER_CC
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_NO_ASM_CLOBBER_CC)
+#define BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC "cc"
+#define BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "cc",
+#else
+#define BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+#define BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA
+#endif
+
+#if (defined(__i386__) || defined(__x86_64__)) && (defined(__clang__) || (defined(BOOST_GCC) && (BOOST_GCC+0) < 40500) || defined(__SUNPRO_CC))
+// This macro indicates that the compiler does not support allocating eax:edx or rax:rdx register pairs ("A") in asm blocks
+#define BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS
+#endif
+
+#if defined(__i386__) && (defined(__PIC__) || defined(__PIE__)) && !(defined(__clang__) || (defined(BOOST_GCC) && (BOOST_GCC+0) >= 50100))
+// This macro indicates that asm blocks should preserve ebx value unchanged. Some compilers are able to maintain ebx themselves
+// around the asm blocks. For those compilers we don't need to save/restore ebx in asm blocks.
+#define BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX
+#endif
+
+#if defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
+#if !(defined(BOOST_LIBSTDCXX11) && (BOOST_LIBSTDCXX_VERSION+0) >= 40700) /* libstdc++ from gcc >= 4.7 in C++11 mode */
+// This macro indicates that there is not even a basic <type_traits> standard header that is sufficient for most Boost.Atomic needs.
+#define BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS
+#endif
+#endif // defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
+
+#if defined(BOOST_NO_CXX11_ALIGNAS) ||\
+    (defined(BOOST_GCC) && (BOOST_GCC+0) < 40900) ||\
+    (defined(BOOST_MSVC) && (BOOST_MSVC+0) < 1910 && defined(_M_IX86))
+// gcc prior to 4.9 doesn't support alignas with a constant expression as an argument.
+// MSVC 14.0 does support alignas, but in 32-bit mode emits "error C2719: formal parameter with requested alignment of N won't be aligned" for N > 4,
+// when aligned types are used in function arguments, even though the std::max_align_t type has alignment of 8.
+#define BOOST_ATOMIC_DETAIL_NO_CXX11_ALIGNAS
+#endif
+
+#if defined(BOOST_NO_CXX11_CONSTEXPR) || (defined(BOOST_GCC) && (BOOST_GCC+0) < 40800)
+// This macro indicates that the compiler doesn't support constexpr constructors that initialize one member
+// of an anonymous union member of the class.
+#define BOOST_ATOMIC_DETAIL_NO_CXX11_CONSTEXPR_UNION_INIT
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_CONSTEXPR_UNION_INIT)
+#define BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT BOOST_CONSTEXPR
+#else
+#define BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT
+#endif
+
+// Enable pointer/reference casts between storage and value when possible.
+// Note: Despite that MSVC does not employ strict aliasing rules for optimizations
+// and does not require an explicit markup for types that may alias, we still don't
+// enable the optimization for this compiler because at least MSVC-8 and 9 are known
+// to generate broken code sometimes when casts are used.
+#define BOOST_ATOMIC_DETAIL_MAY_ALIAS BOOST_MAY_ALIAS
+#if !defined(BOOST_NO_MAY_ALIAS)
+#define BOOST_ATOMIC_DETAIL_STORAGE_TYPE_MAY_ALIAS
+#endif
+
+#if defined(__GCC_ASM_FLAG_OUTPUTS__)
+// The compiler supports output values in flag registers.
+// See: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html, Section 6.44.3.
+#define BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS
+#endif
+
+#if defined(BOOST_INTEL) || (defined(BOOST_GCC) && (BOOST_GCC+0) < 40700) ||\
+    (defined(BOOST_CLANG) && !defined(__apple_build_version__) && ((__clang_major__+0) * 100 + (__clang_minor__+0)) < 302) ||\
+    (defined(__clang__) && defined(__apple_build_version__) && ((__clang_major__+0) * 100 + (__clang_minor__+0)) < 402)
+// Intel compiler (at least 18.0 update 1) breaks if noexcept specification is used in defaulted function declarations:
+// error: the default constructor of "boost::atomics::atomic<T>" cannot be referenced -- it is a deleted function
+// GCC 4.6 doesn't seem to support that either. Clang 3.1 deduces wrong noexcept for the defaulted function and fails as well.
+#define BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL
+#define BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL BOOST_NOEXCEPT
+#else
+#define BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL BOOST_NOEXCEPT
+#define BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL
+#endif
+
+#if defined(__has_builtin)
+#if __has_builtin(__builtin_constant_p)
+#define BOOST_ATOMIC_DETAIL_IS_CONSTANT(x) __builtin_constant_p(x)
+#endif
+#elif defined(__GNUC__)
+#define BOOST_ATOMIC_DETAIL_IS_CONSTANT(x) __builtin_constant_p(x)
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_IS_CONSTANT)
+#define BOOST_ATOMIC_DETAIL_IS_CONSTANT(x) false
+#endif
+
+#if (defined(__BYTE_ORDER__) && defined(__FLOAT_WORD_ORDER__) && (__BYTE_ORDER__+0) == (__FLOAT_WORD_ORDER__+0)) ||\
+    defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)
+// This macro indicates that integer and floating point endianness is the same
+#define BOOST_ATOMIC_DETAIL_INT_FP_ENDIAN_MATCH
+#endif
+
+// Deprecated symbols markup
+#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && defined(_MSC_VER)
+#if (_MSC_VER) >= 1400
+#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __declspec(deprecated(msg))
+#else
+// MSVC 7.1 only supports the attribute without a message
+#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __declspec(deprecated)
+#endif
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && defined(__has_extension)
+#if __has_extension(attribute_deprecated_with_message)
+#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __attribute__((deprecated(msg)))
+#endif
+#endif
+
+// gcc since 4.5 supports deprecated attribute with a message; older versions support the attribute without a message.
+// Oracle Studio 12.4 supports deprecated attribute with a message; this is the first release that supports the attribute.
+#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && (\
+    (defined(__GNUC__) && ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0)) >= 405) ||\
+    (defined(__SUNPRO_CC) && (__SUNPRO_CC + 0) >= 0x5130))
+#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __attribute__((deprecated(msg)))
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && __cplusplus >= 201402
+#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) [[deprecated(msg)]]
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && defined(__GNUC__)
+#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __attribute__((deprecated))
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED) && defined(__has_attribute)
+#if __has_attribute(deprecated)
+#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg) __attribute__((deprecated))
+#endif
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_DEPRECATED)
+#define BOOST_ATOMIC_DETAIL_DEPRECATED(msg)
+#endif
+
+// In Boost.Atomic 1.73 we deprecated atomic<>::storage() accessor in favor of atomic<>::value(). In future releases storage() will be removed.
+#if !defined(BOOST_ATOMIC_SILENCE_STORAGE_DEPRECATION)
+#define BOOST_ATOMIC_DETAIL_STORAGE_DEPRECATED BOOST_ATOMIC_DETAIL_DEPRECATED("Boost.Atomic 1.73 has deprecated atomic<>::storage() in favor of atomic<>::value() and atomic<>::storage_type in favor of atomic<>::value_type. You can define BOOST_ATOMIC_SILENCE_STORAGE_DEPRECATION to disable this warning.")
+#else
+#define BOOST_ATOMIC_DETAIL_STORAGE_DEPRECATED
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_CONFIG_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/extra_fp_operations.hpp b/ThirdParty/boost/atomic/detail/extra_fp_operations.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..854d8c9bee6effe7ea20cdc980d26be9792c8376
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/extra_fp_operations.hpp
@@ -0,0 +1,28 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/extra_fp_operations.hpp
+ *
+ * This header defines extra floating point atomic operations, including the generic version.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_HPP_INCLUDED_
+
+#include <boost/atomic/detail/extra_fp_ops_generic.hpp>
+#include <boost/atomic/detail/extra_fp_ops_emulated.hpp>
+
+#if !defined(BOOST_ATOMIC_DETAIL_EXTRA_FP_BACKEND_GENERIC)
+#include BOOST_ATOMIC_DETAIL_EXTRA_FP_BACKEND_HEADER(boost/atomic/detail/extra_fp_ops_)
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/extra_fp_operations_fwd.hpp b/ThirdParty/boost/atomic/detail/extra_fp_operations_fwd.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..79bca9d2cd243f47cd779e1ed3109ace18a471bd
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/extra_fp_operations_fwd.hpp
@@ -0,0 +1,35 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/extra_fp_operations_fwd.hpp
+ *
+ * This header contains forward declaration of the \c extra_fp_operations template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_FWD_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_FWD_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< typename Base, typename Value, std::size_t Size, bool = Base::is_always_lock_free >
+struct extra_fp_operations;
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_EXTRA_FP_OPERATIONS_FWD_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/extra_fp_ops_emulated.hpp b/ThirdParty/boost/atomic/detail/extra_fp_ops_emulated.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..043ee13e03580c206b818f46b314f1675bdf877f
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/extra_fp_ops_emulated.hpp
@@ -0,0 +1,107 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/extra_fp_ops_emulated.hpp
+ *
+ * This header contains emulated (lock-based) implementation of the extra floating point atomic operations.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_EMULATED_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_EMULATED_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/bitwise_fp_cast.hpp>
+#include <boost/atomic/detail/extra_fp_operations_fwd.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+//! Generic implementation of extra floating point operations
+template< typename Base, typename Value, std::size_t Size >
+struct emulated_extra_fp_operations :
+    public Base
+{
+    typedef Base base_type;
+    typedef typename base_type::storage_type storage_type;
+    typedef Value value_type;
+    typedef typename base_type::scoped_lock scoped_lock;
+
+    static BOOST_FORCEINLINE value_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s);
+        value_type new_val = -old_val;
+        s = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE value_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s);
+        value_type new_val = -old_val;
+        s = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE value_type add(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s);
+        value_type new_val = old_val + v;
+        s = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE value_type sub(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s);
+        value_type new_val = old_val - v;
+        s = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        fetch_negate(storage, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_add(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_sub(storage, v, order);
+    }
+};
+
+template< typename Base, typename Value, std::size_t Size >
+struct extra_fp_operations< Base, Value, Size, false > :
+    public emulated_extra_fp_operations< Base, Value, Size >
+{
+};
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_EMULATED_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/extra_fp_ops_generic.hpp b/ThirdParty/boost/atomic/detail/extra_fp_ops_generic.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..410afe3eb4f4c038be5b94aa7fb8a4a02516ca63
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/extra_fp_ops_generic.hpp
@@ -0,0 +1,189 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/extra_fp_ops_generic.hpp
+ *
+ * This header contains generic implementation of the extra floating point atomic operations.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_GENERIC_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_GENERIC_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/bitwise_fp_cast.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/extra_fp_operations_fwd.hpp>
+#include <boost/atomic/detail/type_traits/is_iec559.hpp>
+#include <boost/atomic/detail/type_traits/is_integral.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(BOOST_GCC) && (BOOST_GCC+0) >= 60000
+#pragma GCC diagnostic push
+// ignoring attributes on template argument X - this warning is because we need to pass storage_type as a template argument; no problem in this case
+#pragma GCC diagnostic ignored "-Wignored-attributes"
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+//! Negate implementation
+template<
+    typename Base,
+    typename Value,
+    std::size_t Size
+#if defined(BOOST_ATOMIC_DETAIL_INT_FP_ENDIAN_MATCH)
+    , bool = atomics::detail::is_iec559< Value >::value && atomics::detail::is_integral< typename Base::storage_type >::value
+#endif
+>
+struct generic_extra_fp_negate :
+    public Base
+{
+    typedef Base base_type;
+    typedef typename base_type::storage_type storage_type;
+    typedef Value value_type;
+
+    static BOOST_FORCEINLINE value_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_storage, new_storage;
+        value_type old_val, new_val;
+        atomics::detail::non_atomic_load(storage, old_storage);
+        do
+        {
+            old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage);
+            new_val = -old_val;
+            new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
+        }
+        while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed));
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE value_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_storage, new_storage;
+        value_type old_val, new_val;
+        atomics::detail::non_atomic_load(storage, old_storage);
+        do
+        {
+            old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage);
+            new_val = -old_val;
+            new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
+        }
+        while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed));
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        fetch_negate(storage, order);
+    }
+};
+
+#if defined(BOOST_ATOMIC_DETAIL_INT_FP_ENDIAN_MATCH)
+
+//! Negate implementation for IEEE 754 / IEC 559 floating point types. We leverage the fact that the sign bit is the most significant bit in the value.
+template< typename Base, typename Value, std::size_t Size >
+struct generic_extra_fp_negate< Base, Value, Size, true > :
+    public Base
+{
+    typedef Base base_type;
+    typedef typename base_type::storage_type storage_type;
+    typedef Value value_type;
+
+    //! The mask with only one sign bit set to 1
+    static BOOST_CONSTEXPR_OR_CONST storage_type sign_mask = static_cast< storage_type >(1u) << (atomics::detail::value_sizeof< value_type >::value * 8u - 1u);
+
+    static BOOST_FORCEINLINE value_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return atomics::detail::bitwise_fp_cast< value_type >(base_type::fetch_xor(storage, sign_mask, order));
+    }
+
+    static BOOST_FORCEINLINE value_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return atomics::detail::bitwise_fp_cast< value_type >(base_type::bitwise_xor(storage, sign_mask, order));
+    }
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::opaque_xor(storage, sign_mask, order);
+    }
+};
+
+#endif // defined(BOOST_ATOMIC_DETAIL_INT_FP_ENDIAN_MATCH)
+
+//! Generic implementation of floating point operations
+template< typename Base, typename Value, std::size_t Size >
+struct generic_extra_fp_operations :
+    public generic_extra_fp_negate< Base, Value, Size >
+{
+    typedef generic_extra_fp_negate< Base, Value, Size > base_type;
+    typedef typename base_type::storage_type storage_type;
+    typedef Value value_type;
+
+    static BOOST_FORCEINLINE value_type add(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_storage, new_storage;
+        value_type old_val, new_val;
+        atomics::detail::non_atomic_load(storage, old_storage);
+        do
+        {
+            old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage);
+            new_val = old_val + v;
+            new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
+        }
+        while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed));
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE value_type sub(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_storage, new_storage;
+        value_type old_val, new_val;
+        atomics::detail::non_atomic_load(storage, old_storage);
+        do
+        {
+            old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage);
+            new_val = old_val - v;
+            new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
+        }
+        while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed));
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_add(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_sub(storage, v, order);
+    }
+};
+
+// Default extra_fp_operations template definition will be used unless specialized for a specific platform
+template< typename Base, typename Value, std::size_t Size >
+struct extra_fp_operations< Base, Value, Size, true > :
+    public generic_extra_fp_operations< Base, Value, Size >
+{
+};
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#if defined(BOOST_GCC) && (BOOST_GCC+0) >= 60000
+#pragma GCC diagnostic pop
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_FP_OPS_GENERIC_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/extra_operations.hpp b/ThirdParty/boost/atomic/detail/extra_operations.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c04f55cd834c85ea38332bd0733007ff1c1e6a79
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/extra_operations.hpp
@@ -0,0 +1,28 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2017 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/extra_operations.hpp
+ *
+ * This header defines extra atomic operations, including the generic version.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_HPP_INCLUDED_
+
+#include <boost/atomic/detail/extra_ops_generic.hpp>
+#include <boost/atomic/detail/extra_ops_emulated.hpp>
+
+#if !defined(BOOST_ATOMIC_DETAIL_EXTRA_BACKEND_GENERIC)
+#include BOOST_ATOMIC_DETAIL_EXTRA_BACKEND_HEADER(boost/atomic/detail/extra_ops_)
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/extra_operations_fwd.hpp b/ThirdParty/boost/atomic/detail/extra_operations_fwd.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..399a8233515e3909bbb2c0a1fb71ea7da940568d
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/extra_operations_fwd.hpp
@@ -0,0 +1,35 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2017 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/extra_operations_fwd.hpp
+ *
+ * This header contains forward declaration of the \c extra_operations template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_FWD_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_FWD_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< typename Base, std::size_t Size, bool Signed, bool = Base::is_always_lock_free >
+struct extra_operations;
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPERATIONS_FWD_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/extra_ops_emulated.hpp b/ThirdParty/boost/atomic/detail/extra_ops_emulated.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4c0e21080042fa334abf36e83942e5f338a04958
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/extra_ops_emulated.hpp
@@ -0,0 +1,238 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/extra_ops_emulated.hpp
+ *
+ * This header contains emulated (lock-based) implementation of the extra atomic operations.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/extra_operations_fwd.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(BOOST_MSVC)
+#pragma warning(push)
+// unary minus operator applied to unsigned type, result still unsigned
+#pragma warning(disable: 4146)
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+//! Generic implementation of extra operations
+template< typename Base, std::size_t Size, bool Signed >
+struct emulated_extra_operations :
+    public Base
+{
+    typedef Base base_type;
+    typedef typename base_type::storage_type storage_type;
+    typedef typename base_type::scoped_lock scoped_lock;
+
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        storage_type old_val = s;
+        s = static_cast< storage_type >(-old_val);
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        storage_type new_val = static_cast< storage_type >(-s);
+        s = new_val;
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        storage_type new_val = s;
+        new_val += v;
+        s = new_val;
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        storage_type new_val = s;
+        new_val -= v;
+        s = new_val;
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        storage_type new_val = s;
+        new_val &= v;
+        s = new_val;
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        storage_type new_val = s;
+        new_val |= v;
+        s = new_val;
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        storage_type new_val = s;
+        new_val ^= v;
+        s = new_val;
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        storage_type old_val = s;
+        s = static_cast< storage_type >(~old_val);
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        storage_type new_val = static_cast< storage_type >(~s);
+        s = new_val;
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        Base::fetch_add(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        Base::fetch_sub(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        fetch_negate(storage, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        Base::fetch_and(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        Base::fetch_or(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        Base::fetch_xor(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        fetch_complement(storage, order);
+    }
+
+    static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!add(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!sub(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!negate(storage, order);
+    }
+
+    static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!bitwise_and(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!bitwise_or(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!bitwise_xor(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!bitwise_complement(storage, order);
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number);
+        storage_type old_val = Base::fetch_or(storage, mask, order);
+        return !!(old_val & mask);
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number);
+        storage_type old_val = Base::fetch_and(storage, ~mask, order);
+        return !!(old_val & mask);
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number);
+        storage_type old_val = Base::fetch_xor(storage, mask, order);
+        return !!(old_val & mask);
+    }
+};
+
+template< typename Base, std::size_t Size, bool Signed >
+struct extra_operations< Base, Size, Signed, false > :
+    public emulated_extra_operations< Base, Size, Signed >
+{
+};
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#if defined(BOOST_MSVC)
+#pragma warning(pop)
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/extra_ops_gcc_arm.hpp b/ThirdParty/boost/atomic/detail/extra_ops_gcc_arm.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2b10cc4c5f448641d41d0ca1562326604e8381b2
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/extra_ops_gcc_arm.hpp
@@ -0,0 +1,1111 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2017 - 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/extra_ops_gcc_arm.hpp
+ *
+ * This header contains implementation of the extra atomic operations for ARM.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_ARM_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_ARM_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/cstdint.hpp>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/platform.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/extra_operations_fwd.hpp>
+#include <boost/atomic/detail/extra_ops_generic.hpp>
+#include <boost/atomic/detail/ops_gcc_arm_common.hpp>
+#include <boost/atomic/capabilities.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< typename Base >
+struct gcc_arm_extra_operations_common :
+    public Base
+{
+    typedef Base base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_negate(storage, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_complement(storage, order);
+    }
+
+    static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!base_type::negate(storage, order);
+    }
+
+    static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!base_type::add(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!base_type::sub(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!base_type::bitwise_and(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!base_type::bitwise_or(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!base_type::bitwise_xor(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!base_type::bitwise_complement(storage, order);
+    }
+};
+
+template< typename Base, std::size_t Size, bool Signed >
+struct gcc_arm_extra_operations;
+
+#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB)
+
+template< typename Base, bool Signed >
+struct gcc_arm_extra_operations< Base, 1u, Signed > :
+    public generic_extra_operations< Base, 1u, Signed >
+{
+    typedef generic_extra_operations< Base, 1u, Signed > base_type;
+    typedef typename base_type::storage_type storage_type;
+    typedef typename storage_traits< 4u >::type extended_storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexb   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "rsb      %[result], %[original], #0\n"        // result = 0 - original
+            "strexb   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(original);
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexb   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "rsb      %[result], %[original], #0\n"        // result = 0 - original
+            "strexb   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexb   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "add      %[result], %[original], %[value]\n"  // result = original + value
+            "strexb   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexb   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "sub      %[result], %[original], %[value]\n"  // result = original - value
+            "strexb   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexb   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "and      %[result], %[original], %[value]\n"  // result = original & value
+            "strexb   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexb   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "orr      %[result], %[original], %[value]\n"  // result = original | value
+            "strexb   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexb   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "eor      %[result], %[original], %[value]\n"  // result = original ^ value
+            "strexb   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexb   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "mvn      %[result], %[original]\n"            // result = NOT original
+            "strexb   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(original);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexb   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "mvn      %[result], %[original]\n"            // result = NOT original
+            "strexb   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(result);
+    }
+};
+
+template< typename Base, bool Signed >
+struct extra_operations< Base, 1u, Signed, true > :
+    public gcc_arm_extra_operations_common< gcc_arm_extra_operations< Base, 1u, Signed > >
+{
+};
+
+#endif // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB)
+
+#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH)
+
+template< typename Base, bool Signed >
+struct gcc_arm_extra_operations< Base, 2u, Signed > :
+    public generic_extra_operations< Base, 2u, Signed >
+{
+    typedef generic_extra_operations< Base, 2u, Signed > base_type;
+    typedef typename base_type::storage_type storage_type;
+    typedef typename storage_traits< 4u >::type extended_storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexh   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "rsb      %[result], %[original], #0\n"        // result = 0 - original
+            "strexh   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(original);
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexh   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "rsb      %[result], %[original], #0\n"        // result = 0 - original
+            "strexh   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexh   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "add      %[result], %[original], %[value]\n"  // result = original + value
+            "strexh   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexh   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "sub      %[result], %[original], %[value]\n"  // result = original - value
+            "strexh   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexh   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "and      %[result], %[original], %[value]\n"  // result = original & value
+            "strexh   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexh   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "orr      %[result], %[original], %[value]\n"  // result = original | value
+            "strexh   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexh   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "eor      %[result], %[original], %[value]\n"  // result = original ^ value
+            "strexh   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexh   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "mvn      %[result], %[original]\n"            // result = NOT original
+            "strexh   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(original);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexh   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "mvn      %[result], %[original]\n"            // result = NOT original
+            "strexh   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return static_cast< storage_type >(result);
+    }
+};
+
+template< typename Base, bool Signed >
+struct extra_operations< Base, 2u, Signed, true > :
+    public gcc_arm_extra_operations_common< gcc_arm_extra_operations< Base, 2u, Signed > >
+{
+};
+
+#endif // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH)
+
+template< typename Base, bool Signed >
+struct gcc_arm_extra_operations< Base, 4u, Signed > :
+    public generic_extra_operations< Base, 4u, Signed >
+{
+    typedef generic_extra_operations< Base, 4u, Signed > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex    %[original], %[storage]\n"           // original = *(&storage)
+            "rsb      %[result], %[original], #0\n"        // result = 0 - original
+            "strex    %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex    %[original], %[storage]\n"           // original = *(&storage)
+            "rsb      %[result], %[original], #0\n"        // result = 0 - original
+            "strex    %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "add     %[result], %[original], %[value]\n"  // result = original + value
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "sub     %[result], %[original], %[value]\n"  // result = original - value
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "and     %[result], %[original], %[value]\n"  // result = original & value
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "orr     %[result], %[original], %[value]\n"  // result = original | value
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "eor     %[result], %[original], %[value]\n"  // result = original ^ value
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex    %[original], %[storage]\n"           // original = *(&storage)
+            "mvn      %[result], %[original]\n"            // result = NOT original
+            "strex    %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex    %[original], %[storage]\n"           // original = *(&storage)
+            "mvn      %[result], %[original]\n"            // result = NOT original
+            "strex    %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return result;
+    }
+};
+
+template< typename Base, bool Signed >
+struct extra_operations< Base, 4u, Signed, true > :
+    public gcc_arm_extra_operations_common< gcc_arm_extra_operations< Base, 4u, Signed > >
+{
+};
+
+#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD)
+
+template< typename Base, bool Signed >
+struct gcc_arm_extra_operations< Base, 8u, Signed > :
+    public generic_extra_operations< Base, 8u, Signed >
+{
+    typedef generic_extra_operations< Base, 8u, Signed > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        storage_type original, result;
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "1:\n"
+            "ldrexd  %1, %H1, [%3]\n"               // original = *(&storage)
+            "mvn     %2, %1\n"                      // result = NOT original
+            "mvn     %H2, %H1\n"
+            "adds    %2, %2, #1\n"                  // result = result + 1
+            "adc     %H2, %H2, #0\n"
+            "strexd  %0, %2, %H2, [%3]\n"           // *(&storage) = result, tmp = store failed
+            "teq     %0, #0\n"                      // flags = tmp==0
+            "bne     1b\n"                          // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original),  // %1
+              "=&r" (result)     // %2
+            : "r" (&storage)     // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        storage_type original, result;
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "1:\n"
+            "ldrexd  %1, %H1, [%3]\n"               // original = *(&storage)
+            "mvn     %2, %1\n"                      // result = NOT original
+            "mvn     %H2, %H1\n"
+            "adds    %2, %2, #1\n"                  // result = result + 1
+            "adc     %H2, %H2, #0\n"
+            "strexd  %0, %2, %H2, [%3]\n"           // *(&storage) = result, tmp = store failed
+            "teq     %0, #0\n"                      // flags = tmp==0
+            "bne     1b\n"                          // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original),  // %1
+              "=&r" (result)     // %2
+            : "r" (&storage)     // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        storage_type original, result;
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "1:\n"
+            "ldrexd  %1, %H1, [%3]\n"               // original = *(&storage)
+            "adds    %2, %1, %4\n"                  // result = original + value
+            "adc     %H2, %H1, %H4\n"
+            "strexd  %0, %2, %H2, [%3]\n"           // *(&storage) = result, tmp = store failed
+            "teq     %0, #0\n"                      // flags = tmp==0
+            "bne     1b\n"                          // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original),  // %1
+              "=&r" (result)     // %2
+            : "r" (&storage),    // %3
+              "r" (v)            // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        storage_type original, result;
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "1:\n"
+            "ldrexd  %1, %H1, [%3]\n"               // original = *(&storage)
+            "subs    %2, %1, %4\n"                  // result = original - value
+            "sbc     %H2, %H1, %H4\n"
+            "strexd  %0, %2, %H2, [%3]\n"           // *(&storage) = result, tmp = store failed
+            "teq     %0, #0\n"                      // flags = tmp==0
+            "bne     1b\n"                          // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original),  // %1
+              "=&r" (result)     // %2
+            : "r" (&storage),    // %3
+              "r" (v)            // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        storage_type original, result;
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "1:\n"
+            "ldrexd  %1, %H1, [%3]\n"               // original = *(&storage)
+            "and     %2, %1, %4\n"                  // result = original & value
+            "and     %H2, %H1, %H4\n"
+            "strexd  %0, %2, %H2, [%3]\n"           // *(&storage) = result, tmp = store failed
+            "teq     %0, #0\n"                      // flags = tmp==0
+            "bne     1b\n"                          // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original),  // %1
+              "=&r" (result)     // %2
+            : "r" (&storage),    // %3
+              "r" (v)            // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        storage_type original, result;
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "1:\n"
+            "ldrexd  %1, %H1, [%3]\n"               // original = *(&storage)
+            "orr     %2, %1, %4\n"                  // result = original | value
+            "orr     %H2, %H1, %H4\n"
+            "strexd  %0, %2, %H2, [%3]\n"           // *(&storage) = result, tmp = store failed
+            "teq     %0, #0\n"                      // flags = tmp==0
+            "bne     1b\n"                          // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original),  // %1
+              "=&r" (result)     // %2
+            : "r" (&storage),    // %3
+              "r" (v)            // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        storage_type original, result;
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "1:\n"
+            "ldrexd  %1, %H1, [%3]\n"               // original = *(&storage)
+            "eor     %2, %1, %4\n"                  // result = original ^ value
+            "eor     %H2, %H1, %H4\n"
+            "strexd  %0, %2, %H2, [%3]\n"           // *(&storage) = result, tmp = store failed
+            "teq     %0, #0\n"                      // flags = tmp==0
+            "bne     1b\n"                          // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original),  // %1
+              "=&r" (result)     // %2
+            : "r" (&storage),    // %3
+              "r" (v)            // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        storage_type original, result;
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "1:\n"
+            "ldrexd  %1, %H1, [%3]\n"               // original = *(&storage)
+            "mvn     %2, %1\n"                      // result = NOT original
+            "mvn     %H2, %H1\n"
+            "strexd  %0, %2, %H2, [%3]\n"           // *(&storage) = result, tmp = store failed
+            "teq     %0, #0\n"                      // flags = tmp==0
+            "bne     1b\n"                          // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original),  // %1
+              "=&r" (result)     // %2
+            : "r" (&storage)     // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_arm_operations_base::fence_before(order);
+        storage_type original, result;
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "1:\n"
+            "ldrexd  %1, %H1, [%3]\n"               // original = *(&storage)
+            "mvn     %2, %1\n"                      // result = NOT original
+            "mvn     %H2, %H1\n"
+            "strexd  %0, %2, %H2, [%3]\n"           // *(&storage) = result, tmp = store failed
+            "teq     %0, #0\n"                      // flags = tmp==0
+            "bne     1b\n"                          // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original),  // %1
+              "=&r" (result)     // %2
+            : "r" (&storage)     // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        gcc_arm_operations_base::fence_after(order);
+        return result;
+    }
+};
+
+template< typename Base, bool Signed >
+struct extra_operations< Base, 8u, Signed, true > :
+    public gcc_arm_extra_operations_common< gcc_arm_extra_operations< Base, 8u, Signed > >
+{
+};
+
+#endif // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD)
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_ARM_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/extra_ops_gcc_ppc.hpp b/ThirdParty/boost/atomic/detail/extra_ops_gcc_ppc.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d430ebd056560ee7e5603d8ac8aef3698e09a3a6
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/extra_ops_gcc_ppc.hpp
@@ -0,0 +1,840 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2017 - 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/extra_ops_gcc_ppc.hpp
+ *
+ * This header contains implementation of the extra atomic operations for PowerPC.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_PPC_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_PPC_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/extra_operations_fwd.hpp>
+#include <boost/atomic/detail/extra_ops_generic.hpp>
+#include <boost/atomic/detail/ops_gcc_ppc_common.hpp>
+#include <boost/atomic/capabilities.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< typename Base >
+struct gcc_ppc_extra_operations_common :
+    public Base
+{
+    typedef Base base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_negate(storage, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_complement(storage, order);
+    }
+
+    static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!base_type::negate(storage, order);
+    }
+
+    static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!base_type::add(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!base_type::sub(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!base_type::bitwise_and(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!base_type::bitwise_or(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!base_type::bitwise_xor(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!base_type::bitwise_complement(storage, order);
+    }
+};
+
+template< typename Base, std::size_t Size, bool Signed >
+struct gcc_ppc_extra_operations;
+
+#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
+
+template< typename Base, bool Signed >
+struct gcc_ppc_extra_operations< Base, 1u, Signed > :
+    public generic_extra_operations< Base, 1u, Signed >
+{
+    typedef generic_extra_operations< Base, 1u, Signed > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_ppc_operations_base::fence_before(order);
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lbarx %0,%y2\n\t"
+            "neg %1,%0\n\t"
+            "stbcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_ppc_operations_base::fence_before(order);
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lbarx %0,%y2\n\t"
+            "neg %1,%0\n\t"
+            "stbcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lbarx %0,%y2\n\t"
+            "add %1,%0,%3\n\t"
+            "stbcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lbarx %0,%y2\n\t"
+            "sub %1,%0,%3\n\t"
+            "stbcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lbarx %0,%y2\n\t"
+            "and %1,%0,%3\n\t"
+            "stbcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lbarx %0,%y2\n\t"
+            "or %1,%0,%3\n\t"
+            "stbcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lbarx %0,%y2\n\t"
+            "xor %1,%0,%3\n\t"
+            "stbcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_ppc_operations_base::fence_before(order);
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lbarx %0,%y2\n\t"
+            "nor %1,%0,%0\n\t"
+            "stbcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_ppc_operations_base::fence_before(order);
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lbarx %0,%y2\n\t"
+            "nor %1,%0,%0\n\t"
+            "stbcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+};
+
+template< typename Base, bool Signed >
+struct extra_operations< Base, 1u, Signed, true > :
+    public gcc_ppc_extra_operations_common< gcc_ppc_extra_operations< Base, 1u, Signed > >
+{
+};
+
+#endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
+
+#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
+
+template< typename Base, bool Signed >
+struct gcc_ppc_extra_operations< Base, 2u, Signed > :
+    public generic_extra_operations< Base, 2u, Signed >
+{
+    typedef generic_extra_operations< Base, 2u, Signed > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_ppc_operations_base::fence_before(order);
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lharx %0,%y2\n\t"
+            "neg %1,%0\n\t"
+            "sthcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_ppc_operations_base::fence_before(order);
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lharx %0,%y2\n\t"
+            "neg %1,%0\n\t"
+            "sthcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lharx %0,%y2\n\t"
+            "add %1,%0,%3\n\t"
+            "sthcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lharx %0,%y2\n\t"
+            "sub %1,%0,%3\n\t"
+            "sthcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lharx %0,%y2\n\t"
+            "and %1,%0,%3\n\t"
+            "sthcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lharx %0,%y2\n\t"
+            "or %1,%0,%3\n\t"
+            "sthcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lharx %0,%y2\n\t"
+            "xor %1,%0,%3\n\t"
+            "sthcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_ppc_operations_base::fence_before(order);
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lharx %0,%y2\n\t"
+            "nor %1,%0,%0\n\t"
+            "sthcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_ppc_operations_base::fence_before(order);
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lharx %0,%y2\n\t"
+            "nor %1,%0,%0\n\t"
+            "sthcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+};
+
+#endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
+
+template< typename Base, bool Signed >
+struct gcc_ppc_extra_operations< Base, 4u, Signed > :
+    public generic_extra_operations< Base, 4u, Signed >
+{
+    typedef generic_extra_operations< Base, 4u, Signed > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_ppc_operations_base::fence_before(order);
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "neg %1,%0\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_ppc_operations_base::fence_before(order);
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "neg %1,%0\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "add %1,%0,%3\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "sub %1,%0,%3\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "and %1,%0,%3\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "or %1,%0,%3\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "xor %1,%0,%3\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_ppc_operations_base::fence_before(order);
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "nor %1,%0,%0\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_ppc_operations_base::fence_before(order);
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "nor %1,%0,%0\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+};
+
+template< typename Base, bool Signed >
+struct extra_operations< Base, 4u, Signed, true > :
+    public gcc_ppc_extra_operations_common< gcc_ppc_extra_operations< Base, 4u, Signed > >
+{
+};
+
+#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
+
+template< typename Base, bool Signed >
+struct gcc_ppc_extra_operations< Base, 8u, Signed > :
+    public generic_extra_operations< Base, 8u, Signed >
+{
+    typedef generic_extra_operations< Base, 8u, Signed > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_ppc_operations_base::fence_before(order);
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "ldarx %0,%y2\n\t"
+            "neg %1,%0\n\t"
+            "stdcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_ppc_operations_base::fence_before(order);
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "ldarx %0,%y2\n\t"
+            "neg %1,%0\n\t"
+            "stdcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "ldarx %0,%y2\n\t"
+            "add %1,%0,%3\n\t"
+            "stdcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "ldarx %0,%y2\n\t"
+            "sub %1,%0,%3\n\t"
+            "stdcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "ldarx %0,%y2\n\t"
+            "and %1,%0,%3\n\t"
+            "stdcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "ldarx %0,%y2\n\t"
+            "or %1,%0,%3\n\t"
+            "stdcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        gcc_ppc_operations_base::fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "ldarx %0,%y2\n\t"
+            "xor %1,%0,%3\n\t"
+            "stdcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_ppc_operations_base::fence_before(order);
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "ldarx %0,%y2\n\t"
+            "nor %1,%0,%0\n\t"
+            "stdcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        gcc_ppc_operations_base::fence_before(order);
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "ldarx %0,%y2\n\t"
+            "nor %1,%0,%0\n\t"
+            "stdcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        gcc_ppc_operations_base::fence_after(order);
+        return result;
+    }
+};
+
+template< typename Base, bool Signed >
+struct extra_operations< Base, 8u, Signed, true > :
+    public gcc_ppc_extra_operations_common< gcc_ppc_extra_operations< Base, 8u, Signed > >
+{
+};
+
+#endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_ARM_PPC_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/extra_ops_gcc_x86.hpp b/ThirdParty/boost/atomic/detail/extra_ops_gcc_x86.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ddd1ca7fb00df3db5b4a31b36034a4f8f419a75f
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/extra_ops_gcc_x86.hpp
@@ -0,0 +1,1784 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2015 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/extra_ops_gcc_x86.hpp
+ *
+ * This header contains implementation of the extra atomic operations for x86.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_X86_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_X86_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/cstdint.hpp>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/extra_operations_fwd.hpp>
+#include <boost/atomic/detail/extra_ops_generic.hpp>
+#include <boost/atomic/capabilities.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< typename Base, bool Signed >
+struct extra_operations< Base, 1u, Signed, true > :
+    public generic_extra_operations< Base, 1u, Signed >
+{
+    typedef generic_extra_operations< Base, 1u, Signed > base_type;
+    typedef typename base_type::storage_type storage_type;
+    typedef typename storage_traits< 4u >::type temp_storage_type;
+
+#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, original, result)\
+    __asm__ __volatile__\
+    (\
+        ".align 16\n\t"\
+        "1: movzbl %[orig], %2\n\t"\
+        op " %b2\n\t"\
+        "lock; cmpxchgb %b2, %[storage]\n\t"\
+        "jne 1b"\
+        : [orig] "+a" (original), [storage] "+m" (storage), "=&q" (result)\
+        : \
+        : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
+    )
+
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        temp_storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("negb", original, result);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        temp_storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("notb", original, result);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        temp_storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("negb", original, result);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        temp_storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("notb", original, result);
+        return static_cast< storage_type >(result);
+    }
+
+#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
+
+#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, original, result)\
+    __asm__ __volatile__\
+    (\
+        ".align 16\n\t"\
+        "1: mov %[arg], %2\n\t"\
+        op " %%al, %b2\n\t"\
+        "lock; cmpxchgb %b2, %[storage]\n\t"\
+        "jne 1b"\
+        : [orig] "+a" (original), [storage] "+m" (storage), "=&q" (result)\
+        : [arg] "ir" ((temp_storage_type)argument)\
+        : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
+    )
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        temp_storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("andb", v, original, result);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        temp_storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("orb", v, original, result);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        temp_storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("xorb", v, original, result);
+        return static_cast< storage_type >(result);
+    }
+
+#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
+
+    static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!negate(storage, order);
+    }
+
+    static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!bitwise_complement(storage, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; incb %[storage]\n\t"
+                : [storage] "+m" (storage)
+                :
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; addb %[argument], %[storage]\n\t"
+                : [storage] "+m" (storage)
+                : [argument] "iq" (v)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+    }
+
+    static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; decb %[storage]\n\t"
+                : [storage] "+m" (storage)
+                :
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; subb %[argument], %[storage]\n\t"
+                : [storage] "+m" (storage)
+                : [argument] "iq" (v)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+    }
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; negb %[storage]\n\t"
+            : [storage] "+m" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; andb %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage)
+            : [argument] "iq" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; orb %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage)
+            : [argument] "iq" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; xorb %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage)
+            : [argument] "iq" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; notb %[storage]\n\t"
+            : [storage] "+m" (storage)
+            :
+            : "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; incb %[storage]\n\t"
+                : [storage] "+m" (storage), [result] "=@ccnz" (res)
+                :
+                : "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; addb %[argument], %[storage]\n\t"
+                : [storage] "+m" (storage), [result] "=@ccnz" (res)
+                : [argument] "iq" (v)
+                : "memory"
+            );
+        }
+#else
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; incb %[storage]\n\t"
+                "setnz %[result]\n\t"
+                : [storage] "+m" (storage), [result] "=q" (res)
+                :
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; addb %[argument], %[storage]\n\t"
+                "setnz %[result]\n\t"
+                : [storage] "+m" (storage), [result] "=q" (res)
+                : [argument] "iq" (v)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; decb %[storage]\n\t"
+                : [storage] "+m" (storage), [result] "=@ccnz" (res)
+                :
+                : "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; subb %[argument], %[storage]\n\t"
+                : [storage] "+m" (storage), [result] "=@ccnz" (res)
+                : [argument] "iq" (v)
+                : "memory"
+            );
+        }
+#else
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; decb %[storage]\n\t"
+                "setnz %[result]\n\t"
+                : [storage] "+m" (storage), [result] "=q" (res)
+                :
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; subb %[argument], %[storage]\n\t"
+                "setnz %[result]\n\t"
+                : [storage] "+m" (storage), [result] "=q" (res)
+                : [argument] "iq" (v)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; andb %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccnz" (res)
+            : [argument] "iq" (v)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; andb %[argument], %[storage]\n\t"
+            "setnz %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [argument] "iq" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; orb %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccnz" (res)
+            : [argument] "iq" (v)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; orb %[argument], %[storage]\n\t"
+            "setnz %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [argument] "iq" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; xorb %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccnz" (res)
+            : [argument] "iq" (v)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; xorb %[argument], %[storage]\n\t"
+            "setnz %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [argument] "iq" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+};
+
+template< typename Base, bool Signed >
+struct extra_operations< Base, 2u, Signed, true > :
+    public generic_extra_operations< Base, 2u, Signed >
+{
+    typedef generic_extra_operations< Base, 2u, Signed > base_type;
+    typedef typename base_type::storage_type storage_type;
+    typedef typename storage_traits< 4u >::type temp_storage_type;
+
+#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, original, result)\
+    __asm__ __volatile__\
+    (\
+        ".align 16\n\t"\
+        "1: movzwl %[orig], %2\n\t"\
+        op " %w2\n\t"\
+        "lock; cmpxchgw %w2, %[storage]\n\t"\
+        "jne 1b"\
+        : [orig] "+a" (original), [storage] "+m" (storage), "=&q" (result)\
+        : \
+        : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
+    )
+
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        temp_storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("negw", original, result);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        temp_storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("notw", original, result);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        temp_storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("negw", original, result);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        temp_storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("notw", original, result);
+        return static_cast< storage_type >(result);
+    }
+
+#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
+
+#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, original, result)\
+    __asm__ __volatile__\
+    (\
+        ".align 16\n\t"\
+        "1: mov %[arg], %2\n\t"\
+        op " %%ax, %w2\n\t"\
+        "lock; cmpxchgw %w2, %[storage]\n\t"\
+        "jne 1b"\
+        : [orig] "+a" (original), [storage] "+m" (storage), "=&q" (result)\
+        : [arg] "ir" ((temp_storage_type)argument)\
+        : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
+    )
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        temp_storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("andw", v, original, result);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        temp_storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("orw", v, original, result);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        temp_storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("xorw", v, original, result);
+        return static_cast< storage_type >(result);
+    }
+
+#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
+
+    static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!negate(storage, order);
+    }
+
+    static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!bitwise_complement(storage, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; incw %[storage]\n\t"
+                : [storage] "+m" (storage)
+                :
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; addw %[argument], %[storage]\n\t"
+                : [storage] "+m" (storage)
+                : [argument] "iq" (v)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+    }
+
+    static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; decw %[storage]\n\t"
+                : [storage] "+m" (storage)
+                :
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; subw %[argument], %[storage]\n\t"
+                : [storage] "+m" (storage)
+                : [argument] "iq" (v)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+    }
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; negw %[storage]\n\t"
+            : [storage] "+m" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; andw %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage)
+            : [argument] "iq" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; orw %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage)
+            : [argument] "iq" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; xorw %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage)
+            : [argument] "iq" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; notw %[storage]\n\t"
+            : [storage] "+m" (storage)
+            :
+            : "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; incw %[storage]\n\t"
+                : [storage] "+m" (storage), [result] "=@ccnz" (res)
+                :
+                : "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; addw %[argument], %[storage]\n\t"
+                : [storage] "+m" (storage), [result] "=@ccnz" (res)
+                : [argument] "iq" (v)
+                : "memory"
+            );
+        }
+#else
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; incw %[storage]\n\t"
+                "setnz %[result]\n\t"
+                : [storage] "+m" (storage), [result] "=q" (res)
+                :
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; addw %[argument], %[storage]\n\t"
+                "setnz %[result]\n\t"
+                : [storage] "+m" (storage), [result] "=q" (res)
+                : [argument] "iq" (v)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; decw %[storage]\n\t"
+                : [storage] "+m" (storage), [result] "=@ccnz" (res)
+                :
+                : "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; subw %[argument], %[storage]\n\t"
+                : [storage] "+m" (storage), [result] "=@ccnz" (res)
+                : [argument] "iq" (v)
+                : "memory"
+            );
+        }
+#else
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; decw %[storage]\n\t"
+                "setnz %[result]\n\t"
+                : [storage] "+m" (storage), [result] "=q" (res)
+                :
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; subw %[argument], %[storage]\n\t"
+                "setnz %[result]\n\t"
+                : [storage] "+m" (storage), [result] "=q" (res)
+                : [argument] "iq" (v)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; andw %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccnz" (res)
+            : [argument] "iq" (v)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; andw %[argument], %[storage]\n\t"
+            "setnz %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [argument] "iq" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; orw %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccnz" (res)
+            : [argument] "iq" (v)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; orw %[argument], %[storage]\n\t"
+            "setnz %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [argument] "iq" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; xorw %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccnz" (res)
+            : [argument] "iq" (v)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; xorw %[argument], %[storage]\n\t"
+            "setnz %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [argument] "iq" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; btsw %[bit_number], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccc" (res)
+            : [bit_number] "Kq" ((uint16_t)bit_number)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; btsw %[bit_number], %[storage]\n\t"
+            "setc %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [bit_number] "Kq" ((uint16_t)bit_number)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; btrw %[bit_number], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccc" (res)
+            : [bit_number] "Kq" ((uint16_t)bit_number)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; btrw %[bit_number], %[storage]\n\t"
+            "setc %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [bit_number] "Kq" ((uint16_t)bit_number)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; btcw %[bit_number], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccc" (res)
+            : [bit_number] "Kq" ((uint16_t)bit_number)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; btcw %[bit_number], %[storage]\n\t"
+            "setc %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [bit_number] "Kq" ((uint16_t)bit_number)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+};
+
+template< typename Base, bool Signed >
+struct extra_operations< Base, 4u, Signed, true > :
+    public generic_extra_operations< Base, 4u, Signed >
+{
+    typedef generic_extra_operations< Base, 4u, Signed > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, original, result)\
+    __asm__ __volatile__\
+    (\
+        ".align 16\n\t"\
+        "1: mov %[orig], %[res]\n\t"\
+        op " %[res]\n\t"\
+        "lock; cmpxchgl %[res], %[storage]\n\t"\
+        "jne 1b"\
+        : [orig] "+a" (original), [storage] "+m" (storage), [res] "=&r" (result)\
+        : \
+        : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
+    )
+
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("negl", original, result);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("notl", original, result);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("negl", original, result);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("notl", original, result);
+        return result;
+    }
+
+#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
+
+#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, original, result)\
+    __asm__ __volatile__\
+    (\
+        ".align 16\n\t"\
+        "1: mov %[arg], %[res]\n\t"\
+        op " %%eax, %[res]\n\t"\
+        "lock; cmpxchgl %[res], %[storage]\n\t"\
+        "jne 1b"\
+        : [orig] "+a" (original), [storage] "+m" (storage), [res] "=&r" (result)\
+        : [arg] "ir" (argument)\
+        : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
+    )
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("andl", v, original, result);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("orl", v, original, result);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("xorl", v, original, result);
+        return static_cast< storage_type >(result);
+    }
+
+#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
+
+    static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!negate(storage, order);
+    }
+
+    static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!bitwise_complement(storage, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; incl %[storage]\n\t"
+                : [storage] "+m" (storage)
+                :
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; addl %[argument], %[storage]\n\t"
+                : [storage] "+m" (storage)
+                : [argument] "ir" (v)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+    }
+
+    static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; decl %[storage]\n\t"
+                : [storage] "+m" (storage)
+                :
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; subl %[argument], %[storage]\n\t"
+                : [storage] "+m" (storage)
+                : [argument] "ir" (v)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+    }
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; negl %[storage]\n\t"
+            : [storage] "+m" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; andl %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage)
+            : [argument] "ir" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; orl %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage)
+            : [argument] "ir" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; xorl %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage)
+            : [argument] "ir" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; notl %[storage]\n\t"
+            : [storage] "+m" (storage)
+            :
+            : "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; incl %[storage]\n\t"
+                : [storage] "+m" (storage), [result] "=@ccnz" (res)
+                :
+                : "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; addl %[argument], %[storage]\n\t"
+                : [storage] "+m" (storage), [result] "=@ccnz" (res)
+                : [argument] "ir" (v)
+                : "memory"
+            );
+        }
+#else
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; incl %[storage]\n\t"
+                "setnz %[result]\n\t"
+                : [storage] "+m" (storage), [result] "=q" (res)
+                :
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; addl %[argument], %[storage]\n\t"
+                "setnz %[result]\n\t"
+                : [storage] "+m" (storage), [result] "=q" (res)
+                : [argument] "ir" (v)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; decl %[storage]\n\t"
+                : [storage] "+m" (storage), [result] "=@ccnz" (res)
+                :
+                : "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; subl %[argument], %[storage]\n\t"
+                : [storage] "+m" (storage), [result] "=@ccnz" (res)
+                : [argument] "ir" (v)
+                : "memory"
+            );
+        }
+#else
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; decl %[storage]\n\t"
+                "setnz %[result]\n\t"
+                : [storage] "+m" (storage), [result] "=q" (res)
+                :
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; subl %[argument], %[storage]\n\t"
+                "setnz %[result]\n\t"
+                : [storage] "+m" (storage), [result] "=q" (res)
+                : [argument] "ir" (v)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; andl %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccnz" (res)
+            : [argument] "ir" (v)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; andl %[argument], %[storage]\n\t"
+            "setnz %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [argument] "ir" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; orl %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccnz" (res)
+            : [argument] "ir" (v)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; orl %[argument], %[storage]\n\t"
+            "setnz %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [argument] "ir" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; xorl %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccnz" (res)
+            : [argument] "ir" (v)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; xorl %[argument], %[storage]\n\t"
+            "setnz %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [argument] "ir" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; btsl %[bit_number], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccc" (res)
+            : [bit_number] "Kr" ((uint32_t)bit_number)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; btsl %[bit_number], %[storage]\n\t"
+            "setc %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [bit_number] "Kr" ((uint32_t)bit_number)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; btrl %[bit_number], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccc" (res)
+            : [bit_number] "Kr" ((uint32_t)bit_number)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; btrl %[bit_number], %[storage]\n\t"
+            "setc %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [bit_number] "Kr" ((uint32_t)bit_number)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; btcl %[bit_number], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccc" (res)
+            : [bit_number] "Kr" ((uint32_t)bit_number)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; btcl %[bit_number], %[storage]\n\t"
+            "setc %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [bit_number] "Kr" ((uint32_t)bit_number)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+};
+
+#if defined(__x86_64__)
+
+template< typename Base, bool Signed >
+struct extra_operations< Base, 8u, Signed, true > :
+    public generic_extra_operations< Base, 8u, Signed >
+{
+    typedef generic_extra_operations< Base, 8u, Signed > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, original, result)\
+    __asm__ __volatile__\
+    (\
+        ".align 16\n\t"\
+        "1: mov %[orig], %[res]\n\t"\
+        op " %[res]\n\t"\
+        "lock; cmpxchgq %[res], %[storage]\n\t"\
+        "jne 1b"\
+        : [orig] "+a" (original), [storage] "+m" (storage), [res] "=&r" (result)\
+        : \
+        : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
+    )
+
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("negq", original, result);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("notq", original, result);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("negq", original, result);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("notq", original, result);
+        return result;
+    }
+
+#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
+
+#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, original, result)\
+    __asm__ __volatile__\
+    (\
+        ".align 16\n\t"\
+        "1: mov %[arg], %[res]\n\t"\
+        op " %%rax, %[res]\n\t"\
+        "lock; cmpxchgq %[res], %[storage]\n\t"\
+        "jne 1b"\
+        : [orig] "+a" (original), [storage] "+m" (storage), [res] "=&r" (result)\
+        : [arg] "r" (argument)\
+        : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
+    )
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("andq", v, original, result);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("orq", v, original, result);
+        return static_cast< storage_type >(result);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type original = storage;
+        storage_type result;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("xorq", v, original, result);
+        return static_cast< storage_type >(result);
+    }
+
+#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
+
+    static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!negate(storage, order);
+    }
+
+    static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!bitwise_complement(storage, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; incq %[storage]\n\t"
+                : [storage] "+m" (storage)
+                :
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; addq %[argument], %[storage]\n\t"
+                : [storage] "+m" (storage)
+                : [argument] "er" (v)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+    }
+
+    static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; decq %[storage]\n\t"
+                : [storage] "+m" (storage)
+                :
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; subq %[argument], %[storage]\n\t"
+                : [storage] "+m" (storage)
+                : [argument] "er" (v)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+    }
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; negq %[storage]\n\t"
+            : [storage] "+m" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; andq %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage)
+            : [argument] "er" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; orq %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage)
+            : [argument] "er" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; xorq %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage)
+            : [argument] "er" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; notq %[storage]\n\t"
+            : [storage] "+m" (storage)
+            :
+            : "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; incq %[storage]\n\t"
+                : [storage] "+m" (storage), [result] "=@ccnz" (res)
+                :
+                : "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; addq %[argument], %[storage]\n\t"
+                : [storage] "+m" (storage), [result] "=@ccnz" (res)
+                : [argument] "er" (v)
+                : "memory"
+            );
+        }
+#else
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; incq %[storage]\n\t"
+                "setnz %[result]\n\t"
+                : [storage] "+m" (storage), [result] "=q" (res)
+                :
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; addq %[argument], %[storage]\n\t"
+                "setnz %[result]\n\t"
+                : [storage] "+m" (storage), [result] "=q" (res)
+                : [argument] "er" (v)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; decq %[storage]\n\t"
+                : [storage] "+m" (storage), [result] "=@ccnz" (res)
+                :
+                : "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; subq %[argument], %[storage]\n\t"
+                : [storage] "+m" (storage), [result] "=@ccnz" (res)
+                : [argument] "er" (v)
+                : "memory"
+            );
+        }
+#else
+        if (BOOST_ATOMIC_DETAIL_IS_CONSTANT(v) && v == 1)
+        {
+            __asm__ __volatile__
+            (
+                "lock; decq %[storage]\n\t"
+                "setnz %[result]\n\t"
+                : [storage] "+m" (storage), [result] "=q" (res)
+                :
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lock; subq %[argument], %[storage]\n\t"
+                "setnz %[result]\n\t"
+                : [storage] "+m" (storage), [result] "=q" (res)
+                : [argument] "er" (v)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+        }
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; andq %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccnz" (res)
+            : [argument] "er" (v)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; andq %[argument], %[storage]\n\t"
+            "setnz %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [argument] "er" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; orq %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccnz" (res)
+            : [argument] "er" (v)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; orq %[argument], %[storage]\n\t"
+            "setnz %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [argument] "er" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; xorq %[argument], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccnz" (res)
+            : [argument] "er" (v)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; xorq %[argument], %[storage]\n\t"
+            "setnz %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [argument] "er" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; btsq %[bit_number], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccc" (res)
+            : [bit_number] "Kr" ((uint64_t)bit_number)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; btsq %[bit_number], %[storage]\n\t"
+            "setc %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [bit_number] "Kr" ((uint64_t)bit_number)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; btrq %[bit_number], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccc" (res)
+            : [bit_number] "Kr" ((uint64_t)bit_number)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; btrq %[bit_number], %[storage]\n\t"
+            "setc %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [bit_number] "Kr" ((uint64_t)bit_number)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
+    {
+        bool res;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; btcq %[bit_number], %[storage]\n\t"
+            : [storage] "+m" (storage), [result] "=@ccc" (res)
+            : [bit_number] "Kr" ((uint64_t)bit_number)
+            : "memory"
+        );
+#else
+        __asm__ __volatile__
+        (
+            "lock; btcq %[bit_number], %[storage]\n\t"
+            "setc %[result]\n\t"
+            : [storage] "+m" (storage), [result] "=q" (res)
+            : [bit_number] "Kr" ((uint64_t)bit_number)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif
+        return res;
+    }
+};
+
+#endif // defined(__x86_64__)
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_X86_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/extra_ops_generic.hpp b/ThirdParty/boost/atomic/detail/extra_ops_generic.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..30d4c8fb5fa086fe01ef2d01bd7278cb5f59f2b9
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/extra_ops_generic.hpp
@@ -0,0 +1,402 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2015 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/extra_ops_generic.hpp
+ *
+ * This header contains generic implementation of the extra atomic operations.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_GENERIC_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GENERIC_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/integral_conversions.hpp>
+#include <boost/atomic/detail/extra_operations_fwd.hpp>
+#include <boost/atomic/capabilities.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(BOOST_MSVC)
+#pragma warning(push)
+// unary minus operator applied to unsigned type, result still unsigned
+#pragma warning(disable: 4146)
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+//! Generic implementation of extra operations
+template< typename Base, std::size_t Size, bool Signed, bool = Base::full_cas_based >
+struct generic_extra_operations :
+    public Base
+{
+    typedef Base base_type;
+    typedef typename base_type::storage_type storage_type;
+    typedef typename storage_traits< Size >::type emulated_storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_val;
+        atomics::detail::non_atomic_load(storage, old_val);
+        while (!base_type::compare_exchange_weak(storage, old_val, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(-old_val)), order, memory_order_relaxed)) {}
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_val, new_val;
+        atomics::detail::non_atomic_load(storage, old_val);
+        do
+        {
+            new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(-old_val));
+        }
+        while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return base_type::fetch_add(storage, v, order) + v;
+    }
+
+    static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return base_type::fetch_sub(storage, v, order) - v;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return base_type::fetch_and(storage, v, order) & v;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return base_type::fetch_or(storage, v, order) | v;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return base_type::fetch_xor(storage, v, order) ^ v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return base_type::fetch_xor(storage, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(~static_cast< emulated_storage_type >(0u))), order);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(~static_cast< emulated_storage_type >(0u)));
+        return base_type::fetch_xor(storage, mask, order) ^ mask;
+    }
+
+    static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_add(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_sub(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        fetch_negate(storage, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_and(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_or(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_xor(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        fetch_complement(storage, order);
+    }
+
+    static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!static_cast< emulated_storage_type >(add(storage, v, order));
+    }
+
+    static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!static_cast< emulated_storage_type >(sub(storage, v, order));
+    }
+
+    static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!negate(storage, order);
+    }
+
+    static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!bitwise_and(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!bitwise_or(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!bitwise_xor(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!static_cast< emulated_storage_type >(bitwise_complement(storage, order));
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+        const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
+        storage_type old_val = base_type::fetch_or(storage, mask, order);
+        return !!(old_val & mask);
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+        const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
+        storage_type old_val = base_type::fetch_and(storage, ~mask, order);
+        return !!(old_val & mask);
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+        const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
+        storage_type old_val = base_type::fetch_xor(storage, mask, order);
+        return !!(old_val & mask);
+    }
+};
+
+//! Specialization for cases when the platform only natively supports CAS
+template< typename Base, std::size_t Size, bool Signed >
+struct generic_extra_operations< Base, Size, Signed, true > :
+    public Base
+{
+    typedef Base base_type;
+    typedef typename base_type::storage_type storage_type;
+    typedef typename storage_traits< Size >::type emulated_storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_val;
+        atomics::detail::non_atomic_load(storage, old_val);
+        while (!base_type::compare_exchange_weak(storage, old_val, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(-old_val)), order, memory_order_relaxed)) {}
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_val, new_val;
+        atomics::detail::non_atomic_load(storage, old_val);
+        do
+        {
+            new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(-old_val));
+        }
+        while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_val, new_val;
+        atomics::detail::non_atomic_load(storage, old_val);
+        do
+        {
+            new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val + v));
+        }
+        while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_val, new_val;
+        atomics::detail::non_atomic_load(storage, old_val);
+        do
+        {
+            new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val - v));
+        }
+        while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_val, new_val;
+        atomics::detail::non_atomic_load(storage, old_val);
+        do
+        {
+            new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val & v));
+        }
+        while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_val, new_val;
+        atomics::detail::non_atomic_load(storage, old_val);
+        do
+        {
+            new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val | v));
+        }
+        while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_val, new_val;
+        atomics::detail::non_atomic_load(storage, old_val);
+        do
+        {
+            new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val ^ v));
+        }
+        while (!base_type::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return base_type::fetch_xor(storage, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(~static_cast< emulated_storage_type >(0u))), order);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return bitwise_xor(storage, atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(~static_cast< emulated_storage_type >(0u))), order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_add(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_sub(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        fetch_negate(storage, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_and(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_or(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fetch_xor(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        fetch_complement(storage, order);
+    }
+
+    static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!static_cast< emulated_storage_type >(add(storage, v, order));
+    }
+
+    static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!static_cast< emulated_storage_type >(sub(storage, v, order));
+    }
+
+    static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!negate(storage, order);
+    }
+
+    static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!bitwise_and(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!bitwise_or(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!bitwise_xor(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!static_cast< emulated_storage_type >(bitwise_complement(storage, order));
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+        const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
+        storage_type old_val = base_type::fetch_or(storage, mask, order);
+        return !!(old_val & mask);
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+        const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
+        storage_type old_val = base_type::fetch_and(storage, ~mask, order);
+        return !!(old_val & mask);
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+        const storage_type mask = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(static_cast< emulated_storage_type >(1u) << bit_number));
+        storage_type old_val = base_type::fetch_xor(storage, mask, order);
+        return !!(old_val & mask);
+    }
+};
+
+// Default extra_operations template definition will be used unless specialized for a specific platform
+template< typename Base, std::size_t Size, bool Signed >
+struct extra_operations< Base, Size, Signed, true > :
+    public generic_extra_operations< Base, Size, Signed >
+{
+};
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#if defined(BOOST_MSVC)
+#pragma warning(pop)
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_GENERIC_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/extra_ops_msvc_arm.hpp b/ThirdParty/boost/atomic/detail/extra_ops_msvc_arm.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1cc858b86c99151387fe16513523e822d2723027
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/extra_ops_msvc_arm.hpp
@@ -0,0 +1,106 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2017 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/extra_ops_msvc_arm.hpp
+ *
+ * This header contains implementation of the extra atomic operations for ARM.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_ARM_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_ARM_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/interlocked.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/extra_operations_fwd.hpp>
+#include <boost/atomic/detail/extra_ops_generic.hpp>
+#include <boost/atomic/capabilities.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+#if defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR)
+
+template< typename Base, std::size_t Size, bool Signed >
+struct extra_operations< Base, 4u, Signed, true > :
+    public generic_extra_operations< Base, 4u, Signed >
+{
+    typedef generic_extra_operations< Base, 4u, Signed > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_INTERLOCKED_BTS_RELAXED) && defined(BOOST_ATOMIC_INTERLOCKED_BTS_ACQUIRE) && defined(BOOST_ATOMIC_INTERLOCKED_BTS_RELEASE)
+        bool result;
+        switch (order)
+        {
+        case memory_order_relaxed:
+            result = !!BOOST_ATOMIC_INTERLOCKED_BTS_RELAXED(&storage, bit_number);
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            result = !!BOOST_ATOMIC_INTERLOCKED_BTS_ACQUIRE(&storage, bit_number);
+            break;
+        case memory_order_release:
+            result = !!BOOST_ATOMIC_INTERLOCKED_BTS_RELEASE(&storage, bit_number);
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            result = !!BOOST_ATOMIC_INTERLOCKED_BTS(&storage, bit_number);
+            break;
+        }
+        return result;
+#else
+        return !!BOOST_ATOMIC_INTERLOCKED_BTS(&storage, bit_number);
+#endif
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_INTERLOCKED_BTR_RELAXED) && defined(BOOST_ATOMIC_INTERLOCKED_BTR_ACQUIRE) && defined(BOOST_ATOMIC_INTERLOCKED_BTR_RELEASE)
+        bool result;
+        switch (order)
+        {
+        case memory_order_relaxed:
+            result = !!BOOST_ATOMIC_INTERLOCKED_BTR_RELAXED(&storage, bit_number);
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            result = !!BOOST_ATOMIC_INTERLOCKED_BTR_ACQUIRE(&storage, bit_number);
+            break;
+        case memory_order_release:
+            result = !!BOOST_ATOMIC_INTERLOCKED_BTR_RELEASE(&storage, bit_number);
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            result = !!BOOST_ATOMIC_INTERLOCKED_BTR(&storage, bit_number);
+            break;
+        }
+        return result;
+#else
+        return !!BOOST_ATOMIC_INTERLOCKED_BTR(&storage, bit_number);
+#endif
+    }
+};
+
+#endif // defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR)
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_ARM_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/extra_ops_msvc_x86.hpp b/ThirdParty/boost/atomic/detail/extra_ops_msvc_x86.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..75edc83a71a3f334a555238986a3dae1e2502fbf
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/extra_ops_msvc_x86.hpp
@@ -0,0 +1,1336 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2017 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/extra_ops_msvc_x86.hpp
+ *
+ * This header contains implementation of the extra atomic operations for x86.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_X86_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_X86_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/interlocked.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/extra_operations_fwd.hpp>
+#include <boost/atomic/detail/extra_ops_generic.hpp>
+#include <boost/atomic/capabilities.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(BOOST_MSVC)
+#pragma warning(push)
+// frame pointer register 'ebx' modified by inline assembly code
+#pragma warning(disable: 4731)
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+#if defined(_M_IX86)
+
+template< typename Base, bool Signed >
+struct extra_operations< Base, 1u, Signed, true > :
+    public generic_extra_operations< Base, 1u, Signed >
+{
+    typedef generic_extra_operations< Base, 1u, Signed > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        storage_type old_val;
+        __asm
+        {
+            mov ecx, storage
+            movzx eax, byte ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            neg dl
+            lock cmpxchg byte ptr [ecx], dl
+            jne again
+            mov old_val, al
+        };
+        base_type::fence_after(order);
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        storage_type new_val;
+        __asm
+        {
+            mov ecx, storage
+            movzx eax, byte ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            neg dl
+            lock cmpxchg byte ptr [ecx], dl
+            jne again
+            mov new_val, dl
+        };
+        base_type::fence_after(order);
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov ecx, storage
+            movzx eax, byte ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            neg dl
+            lock cmpxchg byte ptr [ecx], dl
+            jne again
+            test dl, dl
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov ecx, storage
+            movzx eax, byte ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            neg dl
+            lock cmpxchg byte ptr [ecx], dl
+            jne again
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edi, storage
+            movzx ecx, v
+            xor edx, edx
+            movzx eax, byte ptr [edi]
+            align 16
+        again:
+            mov dl, al
+            and dl, cl
+            lock cmpxchg byte ptr [edi], dl
+            jne again
+            mov v, dl
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edi, storage
+            movzx ecx, v
+            xor edx, edx
+            movzx eax, byte ptr [edi]
+            align 16
+        again:
+            mov dl, al
+            or dl, cl
+            lock cmpxchg byte ptr [edi], dl
+            jne again
+            mov v, dl
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edi, storage
+            movzx ecx, v
+            xor edx, edx
+            movzx eax, byte ptr [edi]
+            align 16
+        again:
+            mov dl, al
+            xor dl, cl
+            lock cmpxchg byte ptr [edi], dl
+            jne again
+            mov v, dl
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        storage_type old_val;
+        __asm
+        {
+            mov ecx, storage
+            movzx eax, byte ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            not dl
+            lock cmpxchg byte ptr [ecx], dl
+            jne again
+            mov old_val, al
+        };
+        base_type::fence_after(order);
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        storage_type new_val;
+        __asm
+        {
+            mov ecx, storage
+            movzx eax, byte ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            not dl
+            lock cmpxchg byte ptr [ecx], dl
+            jne again
+            mov new_val, dl
+        };
+        base_type::fence_after(order);
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov ecx, storage
+            movzx eax, byte ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            not dl
+            lock cmpxchg byte ptr [ecx], dl
+            jne again
+            test dl, dl
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov ecx, storage
+            movzx eax, byte ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            not dl
+            lock cmpxchg byte ptr [ecx], dl
+            jne again
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock add byte ptr [edx], al
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock sub byte ptr [edx], al
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            lock neg byte ptr [edx]
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock and byte ptr [edx], al
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock or byte ptr [edx], al
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock xor byte ptr [edx], al
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            lock not byte ptr [edx]
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock add byte ptr [edx], al
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock sub byte ptr [edx], al
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock and byte ptr [edx], al
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock or byte ptr [edx], al
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock xor byte ptr [edx], al
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+};
+
+template< typename Base, bool Signed >
+struct extra_operations< Base, 2u, Signed, true > :
+    public generic_extra_operations< Base, 2u, Signed >
+{
+    typedef generic_extra_operations< Base, 2u, Signed > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        storage_type old_val;
+        __asm
+        {
+            mov ecx, storage
+            movzx eax, word ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            neg dx
+            lock cmpxchg word ptr [ecx], dx
+            jne again
+            mov old_val, ax
+        };
+        base_type::fence_after(order);
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        storage_type new_val;
+        __asm
+        {
+            mov ecx, storage
+            movzx eax, word ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            neg dx
+            lock cmpxchg word ptr [ecx], dx
+            jne again
+            mov new_val, dx
+        };
+        base_type::fence_after(order);
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov ecx, storage
+            movzx eax, word ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            neg dx
+            lock cmpxchg word ptr [ecx], dx
+            jne again
+            test dx, dx
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov ecx, storage
+            movzx eax, word ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            neg dx
+            lock cmpxchg word ptr [ecx], dx
+            jne again
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edi, storage
+            movzx ecx, v
+            xor edx, edx
+            movzx eax, word ptr [edi]
+            align 16
+        again:
+            mov dx, ax
+            and dx, cx
+            lock cmpxchg word ptr [edi], dx
+            jne again
+            mov v, dx
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edi, storage
+            movzx ecx, v
+            xor edx, edx
+            movzx eax, word ptr [edi]
+            align 16
+        again:
+            mov dx, ax
+            or dx, cx
+            lock cmpxchg word ptr [edi], dx
+            jne again
+            mov v, dx
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edi, storage
+            movzx ecx, v
+            xor edx, edx
+            movzx eax, word ptr [edi]
+            align 16
+        again:
+            mov dx, ax
+            xor dx, cx
+            lock cmpxchg word ptr [edi], dx
+            jne again
+            mov v, dx
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        storage_type old_val;
+        __asm
+        {
+            mov ecx, storage
+            movzx eax, word ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            not dx
+            lock cmpxchg word ptr [ecx], dx
+            jne again
+            mov old_val, ax
+        };
+        base_type::fence_after(order);
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        storage_type new_val;
+        __asm
+        {
+            mov ecx, storage
+            movzx eax, word ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            not dx
+            lock cmpxchg word ptr [ecx], dx
+            jne again
+            mov new_val, dx
+        };
+        base_type::fence_after(order);
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov ecx, storage
+            movzx eax, word ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            not dx
+            lock cmpxchg word ptr [ecx], dx
+            jne again
+            test dx, dx
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov ecx, storage
+            movzx eax, word ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            not dx
+            lock cmpxchg word ptr [ecx], dx
+            jne again
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock add word ptr [edx], ax
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock sub word ptr [edx], ax
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            lock neg word ptr [edx]
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock and word ptr [edx], ax
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock or word ptr [edx], ax
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock xor word ptr [edx], ax
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            lock not word ptr [edx]
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock add word ptr [edx], ax
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock sub word ptr [edx], ax
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock and word ptr [edx], ax
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock or word ptr [edx], ax
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock xor word ptr [edx], ax
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            mov eax, bit_number
+            lock bts word ptr [edx], ax
+            setc result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            mov eax, bit_number
+            lock btr word ptr [edx], ax
+            setc result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            mov eax, bit_number
+            lock btc word ptr [edx], ax
+            setc result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+};
+
+#endif // defined(_M_IX86)
+
+#if defined(_M_IX86) || (defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR))
+
+template< typename Base, bool Signed >
+struct extra_operations< Base, 4u, Signed, true > :
+    public generic_extra_operations< Base, 4u, Signed >
+{
+    typedef generic_extra_operations< Base, 4u, Signed > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+#if defined(_M_IX86)
+    static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        storage_type old_val;
+        __asm
+        {
+            mov ecx, storage
+            mov eax, dword ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            neg edx
+            lock cmpxchg dword ptr [ecx], edx
+            jne again
+            mov old_val, eax
+        };
+        base_type::fence_after(order);
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        storage_type new_val;
+        __asm
+        {
+            mov ecx, storage
+            mov eax, dword ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            neg edx
+            lock cmpxchg dword ptr [ecx], edx
+            jne again
+            mov new_val, edx
+        };
+        base_type::fence_after(order);
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov ecx, storage
+            mov eax, dword ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            neg edx
+            lock cmpxchg dword ptr [ecx], edx
+            jne again
+            test edx, edx
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov ecx, storage
+            mov eax, dword ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            neg edx
+            lock cmpxchg dword ptr [ecx], edx
+            jne again
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edi, storage
+            mov ecx, v
+            xor edx, edx
+            mov eax, dword ptr [edi]
+            align 16
+        again:
+            mov edx, eax
+            and edx, ecx
+            lock cmpxchg dword ptr [edi], edx
+            jne again
+            mov v, edx
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edi, storage
+            mov ecx, v
+            xor edx, edx
+            mov eax, dword ptr [edi]
+            align 16
+        again:
+            mov edx, eax
+            or edx, ecx
+            lock cmpxchg dword ptr [edi], edx
+            jne again
+            mov v, edx
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edi, storage
+            mov ecx, v
+            xor edx, edx
+            mov eax, dword ptr [edi]
+            align 16
+        again:
+            mov edx, eax
+            xor edx, ecx
+            lock cmpxchg dword ptr [edi], edx
+            jne again
+            mov v, edx
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        storage_type old_val;
+        __asm
+        {
+            mov ecx, storage
+            mov eax, dword ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            not edx
+            lock cmpxchg dword ptr [ecx], edx
+            jne again
+            mov old_val, eax
+        };
+        base_type::fence_after(order);
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        storage_type new_val;
+        __asm
+        {
+            mov ecx, storage
+            mov eax, dword ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            not edx
+            lock cmpxchg dword ptr [ecx], edx
+            jne again
+            mov new_val, edx
+        };
+        base_type::fence_after(order);
+        return new_val;
+    }
+
+    static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov ecx, storage
+            mov eax, dword ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            not edx
+            lock cmpxchg dword ptr [ecx], edx
+            jne again
+            test edx, edx
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov ecx, storage
+            mov eax, dword ptr [ecx]
+            align 16
+        again:
+            mov edx, eax
+            not edx
+            lock cmpxchg dword ptr [ecx], edx
+            jne again
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            mov eax, v
+            lock add dword ptr [edx], eax
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            mov eax, v
+            lock sub dword ptr [edx], eax
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            lock neg dword ptr [edx]
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            mov eax, v
+            lock and dword ptr [edx], eax
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            mov eax, v
+            lock or dword ptr [edx], eax
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            mov eax, v
+            lock xor dword ptr [edx], eax
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            lock not dword ptr [edx]
+        };
+        base_type::fence_after(order);
+    }
+
+    static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            mov eax, v
+            lock add dword ptr [edx], eax
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            mov eax, v
+            lock sub dword ptr [edx], eax
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            mov eax, v
+            lock and dword ptr [edx], eax
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            mov eax, v
+            lock or dword ptr [edx], eax
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            mov eax, v
+            lock xor dword ptr [edx], eax
+            setnz result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            mov eax, bit_number
+            lock btc dword ptr [edx], eax
+            setc result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+#endif // defined(_M_IX86)
+
+#if defined(BOOST_ATOMIC_INTERLOCKED_BTS)
+    static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
+    {
+        return !!BOOST_ATOMIC_INTERLOCKED_BTS(&storage, bit_number);
+    }
+#elif defined(_M_IX86)
+    static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            mov eax, bit_number
+            lock bts dword ptr [edx], eax
+            setc result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+#endif
+
+#if defined(BOOST_ATOMIC_INTERLOCKED_BTR)
+    static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order) BOOST_NOEXCEPT
+    {
+        return !!BOOST_ATOMIC_INTERLOCKED_BTR(&storage, bit_number);
+    }
+#elif defined(_M_IX86)
+    static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        bool result;
+        __asm
+        {
+            mov edx, storage
+            mov eax, bit_number
+            lock btr dword ptr [edx], eax
+            setc result
+        };
+        base_type::fence_after(order);
+        return result;
+    }
+#endif
+};
+
+#endif // defined(_M_IX86) || (defined(BOOST_ATOMIC_INTERLOCKED_BTS) && defined(BOOST_ATOMIC_INTERLOCKED_BTR))
+
+#if defined(BOOST_ATOMIC_INTERLOCKED_BTS64) && defined(BOOST_ATOMIC_INTERLOCKED_BTR64)
+
+template< typename Base, bool Signed >
+struct extra_operations< Base, 8u, Signed, true > :
+    public generic_extra_operations< Base, 8u, Signed >
+{
+    typedef generic_extra_operations< Base, 8u, Signed > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!BOOST_ATOMIC_INTERLOCKED_BTS64(&storage, bit_number);
+    }
+
+    static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!BOOST_ATOMIC_INTERLOCKED_BTR64(&storage, bit_number);
+    }
+};
+
+#endif // defined(BOOST_ATOMIC_INTERLOCKED_BTS64) && defined(BOOST_ATOMIC_INTERLOCKED_BTR64)
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#if defined(BOOST_MSVC)
+#pragma warning(pop)
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_MSVC_X86_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/float_sizes.hpp b/ThirdParty/boost/atomic/detail/float_sizes.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4c3a346f15e1dded11480eaaafdeb53694e4df6b
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/float_sizes.hpp
@@ -0,0 +1,142 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/float_sizes.hpp
+ *
+ * This header defines macros for testing buitin floating point type sizes
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_FLOAT_SIZES_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_FLOAT_SIZES_HPP_INCLUDED_
+
+#include <float.h>
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+// Detect value sizes of the different floating point types. The value sizes may be less than the corresponding type sizes
+// if the type contains padding bits. This is typical e.g. with 80-bit extended float types, which are often represented as 128-bit types.
+// See: https://en.wikipedia.org/wiki/IEEE_754
+// For Intel x87 extended double see: https://en.wikipedia.org/wiki/Extended_precision#x86_Architecture_Extended_Precision_Format
+// For IBM extended double (a.k.a. double-double) see: https://en.wikipedia.org/wiki/Long_double#Implementations, https://gcc.gnu.org/wiki/Ieee128PowerPC
+#if (FLT_RADIX+0) == 2
+
+#if ((FLT_MANT_DIG+0) == 11) && ((FLT_MAX_EXP+0) == 16) // IEEE 754 binary16
+#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 2
+#elif ((FLT_MANT_DIG+0) == 24) && ((FLT_MAX_EXP+0) == 128) // IEEE 754 binary32
+#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 4
+#elif ((FLT_MANT_DIG+0) == 53) && ((FLT_MAX_EXP+0) == 1024) // IEEE 754 binary64
+#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 8
+#elif ((FLT_MANT_DIG+0) == 64) && ((FLT_MAX_EXP+0) == 16384) // x87 extended double
+#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 10
+#elif ((FLT_MANT_DIG+0) == 106) && ((FLT_MAX_EXP+0) == 1024) // IBM extended double
+#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 16
+#elif ((FLT_MANT_DIG+0) == 113) && ((FLT_MAX_EXP+0) == 16384) // IEEE 754 binary128
+#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 16
+#elif ((FLT_MANT_DIG+0) == 237) && ((FLT_MAX_EXP+0) == 262144) // IEEE 754 binary256
+#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 32
+#endif
+
+#if ((DBL_MANT_DIG+0) == 11) && ((DBL_MAX_EXP+0) == 16) // IEEE 754 binary16
+#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 2
+#elif ((DBL_MANT_DIG+0) == 24) && ((DBL_MAX_EXP+0) == 128) // IEEE 754 binary32
+#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 4
+#elif ((DBL_MANT_DIG+0) == 53) && ((DBL_MAX_EXP+0) == 1024) // IEEE 754 binary64
+#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 8
+#elif ((DBL_MANT_DIG+0) == 64) && ((DBL_MAX_EXP+0) == 16384) // x87 extended double
+#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 10
+#elif ((DBL_MANT_DIG+0) == 106) && ((DBL_MAX_EXP+0) == 1024) // IBM extended double
+#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 16
+#elif ((DBL_MANT_DIG+0) == 113) && ((DBL_MAX_EXP+0) == 16384) // IEEE 754 binary128
+#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 16
+#elif ((DBL_MANT_DIG+0) == 237) && ((DBL_MAX_EXP+0) == 262144) // IEEE 754 binary256
+#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 32
+#endif
+
+#if ((LDBL_MANT_DIG+0) == 11) && ((LDBL_MAX_EXP+0) == 16) // IEEE 754 binary16
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 2
+#elif ((LDBL_MANT_DIG+0) == 24) && ((LDBL_MAX_EXP+0) == 128) // IEEE 754 binary32
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 4
+#elif ((LDBL_MANT_DIG+0) == 53) && ((LDBL_MAX_EXP+0) == 1024) // IEEE 754 binary64
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 8
+#elif ((LDBL_MANT_DIG+0) == 64) && ((LDBL_MAX_EXP+0) == 16384) // x87 extended double
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 10
+#elif ((LDBL_MANT_DIG+0) == 106) && ((LDBL_MAX_EXP+0) == 1024) // IBM extended double
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 16
+#elif ((LDBL_MANT_DIG+0) == 113) && ((LDBL_MAX_EXP+0) == 16384) // IEEE 754 binary128
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 16
+#elif ((LDBL_MANT_DIG+0) == 237) && ((LDBL_MAX_EXP+0) == 262144) // IEEE 754 binary256
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 32
+#endif
+
+#elif (FLT_RADIX+0) == 10
+
+#if ((FLT_MANT_DIG+0) == 7) && ((FLT_MAX_EXP+0) == 97) // IEEE 754 decimal32
+#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 4
+#elif ((FLT_MANT_DIG+0) == 16) && ((FLT_MAX_EXP+0) == 385) // IEEE 754 decimal64
+#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 8
+#elif ((FLT_MANT_DIG+0) == 34) && ((FLT_MAX_EXP+0) == 6145) // IEEE 754 decimal128
+#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE 16
+#endif
+
+#if ((DBL_MANT_DIG+0) == 7) && ((DBL_MAX_EXP+0) == 97) // IEEE 754 decimal32
+#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 4
+#elif ((DBL_MANT_DIG+0) == 16) && ((DBL_MAX_EXP+0) == 385) // IEEE 754 decimal64
+#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 8
+#elif ((DBL_MANT_DIG+0) == 34) && ((DBL_MAX_EXP+0) == 6145) // IEEE 754 decimal128
+#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE 16
+#endif
+
+#if ((LDBL_MANT_DIG+0) == 7) && ((LDBL_MAX_EXP+0) == 97) // IEEE 754 decimal32
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 4
+#elif ((LDBL_MANT_DIG+0) == 16) && ((LDBL_MAX_EXP+0) == 385) // IEEE 754 decimal64
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 8
+#elif ((LDBL_MANT_DIG+0) == 34) && ((LDBL_MAX_EXP+0) == 6145) // IEEE 754 decimal128
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE 16
+#endif
+
+#endif
+
+// GCC and compatible compilers define internal macros with builtin type traits
+#if defined(__SIZEOF_FLOAT__)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT __SIZEOF_FLOAT__
+#endif
+#if defined(__SIZEOF_DOUBLE__)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE __SIZEOF_DOUBLE__
+#endif
+#if defined(__SIZEOF_LONG_DOUBLE__)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE __SIZEOF_LONG_DOUBLE__
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE)
+
+#define BOOST_ATOMIC_DETAIL_ALIGN_SIZE_TO_POWER_OF_2(x)\
+    ((x) == 1u ? 1u : ((x) == 2u ? 2u : ((x) <= 4u ? 4u : ((x) <= 8u ? 8u : ((x) <= 16u ? 16u : ((x) <= 32u ? 32u : (x)))))))
+
+// Make our best guess. These sizes may not be accurate, but they are good enough to estimate the size of the storage required to hold these types.
+#if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT BOOST_ATOMIC_DETAIL_ALIGN_SIZE_TO_POWER_OF_2(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE)
+#endif
+#if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE BOOST_ATOMIC_DETAIL_ALIGN_SIZE_TO_POWER_OF_2(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE)
+#endif
+#if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE BOOST_ATOMIC_DETAIL_ALIGN_SIZE_TO_POWER_OF_2(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE)
+#endif
+
+#endif // !defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE)
+
+#if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT_VALUE) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT) ||\
+    !defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE_VALUE) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE) ||\
+    !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE_VALUE) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE)
+#error Boost.Atomic: Failed to determine builtin floating point type sizes, the target platform is not supported. Please, report to the developers (patches are welcome).
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_FLOAT_SIZES_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/fp_operations.hpp b/ThirdParty/boost/atomic/detail/fp_operations.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..69cb0d19a2e065ea0205271156af3b97cb41e8cb
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/fp_operations.hpp
@@ -0,0 +1,28 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/fp_operations.hpp
+ *
+ * This header defines floating point atomic operations, including the generic version.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_FP_OPERATIONS_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_FP_OPERATIONS_HPP_INCLUDED_
+
+#include <boost/atomic/detail/fp_ops_generic.hpp>
+#include <boost/atomic/detail/fp_ops_emulated.hpp>
+
+#if !defined(BOOST_ATOMIC_DETAIL_FP_BACKEND_GENERIC)
+#include BOOST_ATOMIC_DETAIL_FP_BACKEND_HEADER(boost/atomic/detail/fp_ops_)
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_FP_OPERATIONS_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/fp_operations_fwd.hpp b/ThirdParty/boost/atomic/detail/fp_operations_fwd.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..8696de31cf604fb4250e4e3012efa193dbfdfb9f
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/fp_operations_fwd.hpp
@@ -0,0 +1,35 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/fp_operations_fwd.hpp
+ *
+ * This header contains forward declaration of the \c fp_operations template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_FP_OPERATIONS_FWD_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_FP_OPERATIONS_FWD_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< typename Base, typename Value, std::size_t Size, bool = Base::is_always_lock_free >
+struct fp_operations;
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_FP_OPERATIONS_FWD_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/fp_ops_emulated.hpp b/ThirdParty/boost/atomic/detail/fp_ops_emulated.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5beea91e38e56c4855de1a895780828db72e7375
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/fp_ops_emulated.hpp
@@ -0,0 +1,72 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/fp_ops_emulated.hpp
+ *
+ * This header contains emulated (lock-based) implementation of the floating point atomic operations.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_FP_OPS_EMULATED_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_FP_OPS_EMULATED_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/bitwise_fp_cast.hpp>
+#include <boost/atomic/detail/fp_operations_fwd.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+//! Generic implementation of floating point operations
+template< typename Base, typename Value, std::size_t Size >
+struct emulated_fp_operations :
+    public Base
+{
+    typedef Base base_type;
+    typedef typename base_type::storage_type storage_type;
+    typedef Value value_type;
+    typedef typename base_type::scoped_lock scoped_lock;
+
+    static BOOST_FORCEINLINE value_type fetch_add(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s);
+        value_type new_val = old_val + v;
+        s = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE value_type fetch_sub(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s);
+        value_type new_val = old_val - v;
+        s = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
+        return old_val;
+    }
+};
+
+template< typename Base, typename Value, std::size_t Size >
+struct fp_operations< Base, Value, Size, false > :
+    public emulated_fp_operations< Base, Value, Size >
+{
+};
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_FP_OPS_EMULATED_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/fp_ops_generic.hpp b/ThirdParty/boost/atomic/detail/fp_ops_generic.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ba27bb7d3e13e8016ec8a522d8c90488b79d725f
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/fp_ops_generic.hpp
@@ -0,0 +1,83 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/fp_ops_generic.hpp
+ *
+ * This header contains generic implementation of the floating point atomic operations.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_FP_OPS_GENERIC_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_FP_OPS_GENERIC_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/bitwise_fp_cast.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/fp_operations_fwd.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+//! Generic implementation of floating point operations
+template< typename Base, typename Value, std::size_t Size >
+struct generic_fp_operations :
+    public Base
+{
+    typedef Base base_type;
+    typedef typename base_type::storage_type storage_type;
+    typedef Value value_type;
+
+    static BOOST_FORCEINLINE value_type fetch_add(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_storage, new_storage;
+        value_type old_val, new_val;
+        atomics::detail::non_atomic_load(storage, old_storage);
+        do
+        {
+            old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage);
+            new_val = old_val + v;
+            new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
+        }
+        while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed));
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE value_type fetch_sub(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_storage, new_storage;
+        value_type old_val, new_val;
+        atomics::detail::non_atomic_load(storage, old_storage);
+        do
+        {
+            old_val = atomics::detail::bitwise_fp_cast< value_type >(old_storage);
+            new_val = old_val - v;
+            new_storage = atomics::detail::bitwise_fp_cast< storage_type >(new_val);
+        }
+        while (!base_type::compare_exchange_weak(storage, old_storage, new_storage, order, memory_order_relaxed));
+        return old_val;
+    }
+};
+
+// Default fp_operations template definition will be used unless specialized for a specific platform
+template< typename Base, typename Value, std::size_t Size >
+struct fp_operations< Base, Value, Size, true > :
+    public generic_fp_operations< Base, Value, Size >
+{
+};
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_FP_OPS_GENERIC_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/hwcaps_gcc_arm.hpp b/ThirdParty/boost/atomic/detail/hwcaps_gcc_arm.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6d0c33862270ab2d86dc71d4a30bb5a5f188959f
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/hwcaps_gcc_arm.hpp
@@ -0,0 +1,67 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2017 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/hwcaps_gcc_arm.hpp
+ *
+ * This header defines hardware capabilities macros for ARM
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_HWCAPS_GCC_ARM_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_HWCAPS_GCC_ARM_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/platform.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(__GNUC__) && defined(__arm__) && (BOOST_ATOMIC_DETAIL_ARM_ARCH+0) >= 6
+
+#if BOOST_ATOMIC_DETAIL_ARM_ARCH > 6
+// ARMv7 and later have dmb instruction
+#define BOOST_ATOMIC_DETAIL_ARM_HAS_DMB 1
+#endif
+
+#if defined(__ARM_FEATURE_LDREX)
+
+#if (__ARM_FEATURE_LDREX & 1)
+#define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB 1
+#endif
+#if (__ARM_FEATURE_LDREX & 2)
+#define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH 1
+#endif
+#if (__ARM_FEATURE_LDREX & 8)
+#define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD 1
+#endif
+
+#else // defined(__ARM_FEATURE_LDREX)
+
+#if !(defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6Z__))
+
+// ARMv6k and ARMv7 have 8 and 16-bit ldrex/strex variants, but at least GCC 4.7 fails to compile them. GCC 4.9 is known to work.
+#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409
+#define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB 1
+#define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH 1
+#endif
+
+#if !(((defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__)) && defined(__thumb__)) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7M__))
+// ARMv6k and ARMv7 except ARMv7-M have 64-bit ldrex/strex variants.
+// Unfortunately, GCC (at least 4.7.3 on Ubuntu) does not allocate register pairs properly when targeting ARMv6k Thumb,
+// which is required for ldrexd/strexd instructions, so we disable 64-bit support. When targeting ARMv6k ARM
+// or ARMv7 (both ARM and Thumb 2) it works as expected.
+#define BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD 1
+#endif
+
+#endif // !(defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6Z__))
+
+#endif // defined(__ARM_FEATURE_LDREX)
+
+#endif // defined(__GNUC__) && defined(__arm__) && (BOOST_ATOMIC_DETAIL_ARM_ARCH+0) >= 6
+
+#endif // BOOST_ATOMIC_DETAIL_HWCAPS_GCC_ARM_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/hwcaps_gcc_ppc.hpp b/ThirdParty/boost/atomic/detail/hwcaps_gcc_ppc.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2ec1e327a7f0006fdc331d2b382eaf580a22798a
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/hwcaps_gcc_ppc.hpp
@@ -0,0 +1,42 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2017 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/hwcaps_gcc_ppc.hpp
+ *
+ * This header defines hardware capabilities macros for PowerPC
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_HWCAPS_GCC_PPC_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_HWCAPS_GCC_PPC_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(__POWERPC__) || defined(__PPC__)
+
+#if defined(_ARCH_PWR8)
+// Power8 and later architectures have 8 and 16-bit instructions
+#define BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX
+#define BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX
+#endif
+
+#if defined(__powerpc64__) || defined(__PPC64__)
+// Power7 and later architectures in 64-bit mode have 64-bit instructions
+#define BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX
+#if defined(_ARCH_PWR8)
+// Power8 also has 128-bit instructions
+#define BOOST_ATOMIC_DETAIL_PPC_HAS_LQARX_STQCX
+#endif
+#endif
+
+#endif // defined(__POWERPC__) || defined(__PPC__)
+
+#endif // BOOST_ATOMIC_DETAIL_HWCAPS_GCC_PPC_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/hwcaps_gcc_x86.hpp b/ThirdParty/boost/atomic/detail/hwcaps_gcc_x86.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..91a1aee3aae08d26be6a1df49e63c0983a4e8261
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/hwcaps_gcc_x86.hpp
@@ -0,0 +1,58 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2017 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/hwcaps_gcc_x86.hpp
+ *
+ * This header defines hardware capabilities macros for x86
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_HWCAPS_GCC_X86_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_HWCAPS_GCC_X86_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(__GNUC__)
+
+#if defined(__i386__) &&\
+    (\
+        defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) ||\
+        defined(__i586__) || defined(__i686__) || defined(__SSE__)\
+    )
+#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B 1
+#endif
+
+#if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
+#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1
+#endif
+
+#if defined(__x86_64__) || defined(__SSE2__)
+// Use mfence only if SSE2 is available
+#define BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE 1
+#endif
+
+#else // defined(__GNUC__)
+
+#if defined(__i386__) && !defined(BOOST_ATOMIC_NO_CMPXCHG8B)
+#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B 1
+#endif
+
+#if defined(__x86_64__) && !defined(BOOST_ATOMIC_NO_CMPXCHG16B)
+#define BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B 1
+#endif
+
+#if !defined(BOOST_ATOMIC_NO_MFENCE)
+#define BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE 1
+#endif
+
+#endif // defined(__GNUC__)
+
+#endif // BOOST_ATOMIC_DETAIL_HWCAPS_GCC_X86_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/int_sizes.hpp b/ThirdParty/boost/atomic/detail/int_sizes.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2a9757c1472ac0ad7a1b0c6e9b9fcaa7a9bf8fd3
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/int_sizes.hpp
@@ -0,0 +1,140 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/int_sizes.hpp
+ *
+ * This header defines macros for testing buitin integer type sizes
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_INT_SIZES_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_INT_SIZES_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+// GCC and compatible compilers define internal macros with builtin type traits
+#if defined(__SIZEOF_SHORT__)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT __SIZEOF_SHORT__
+#endif
+#if defined(__SIZEOF_INT__)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_INT __SIZEOF_INT__
+#endif
+#if defined(__SIZEOF_LONG__)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG __SIZEOF_LONG__
+#endif
+#if defined(__SIZEOF_LONG_LONG__)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG __SIZEOF_LONG_LONG__
+#endif
+#if defined(__SIZEOF_WCHAR_T__)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T __SIZEOF_WCHAR_T__
+#endif
+#if defined(__SIZEOF_POINTER__)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER __SIZEOF_POINTER__
+#elif defined(_MSC_VER)
+#if defined(_M_AMD64) || defined(_M_ARM64) || defined(_M_IA64)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER 8
+#else
+#define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER 4
+#endif
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_SHORT) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_INT) ||\
+    !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LLONG)
+
+// Try to deduce sizes from limits
+#include <limits.h>
+#include <boost/cstdint.hpp>
+
+#if (USHRT_MAX + 0) == 0xff
+#define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT 1
+#elif (USHRT_MAX + 0) == 0xffff
+#define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT 2
+#elif (USHRT_MAX + 0) == 0xffffffff
+#define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT 4
+#elif (USHRT_MAX + 0) == UINT64_C(0xffffffffffffffff)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT 8
+#endif
+
+#if (UINT_MAX + 0) == 0xff
+#define BOOST_ATOMIC_DETAIL_SIZEOF_INT 1
+#elif (UINT_MAX + 0) == 0xffff
+#define BOOST_ATOMIC_DETAIL_SIZEOF_INT 2
+#elif (UINT_MAX + 0) == 0xffffffff
+#define BOOST_ATOMIC_DETAIL_SIZEOF_INT 4
+#elif (UINT_MAX + 0) == UINT64_C(0xffffffffffffffff)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_INT 8
+#endif
+
+#if (ULONG_MAX + 0) == 0xff
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG 1
+#elif (ULONG_MAX + 0) == 0xffff
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG 2
+#elif (ULONG_MAX + 0) == 0xffffffff
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG 4
+#elif (ULONG_MAX + 0) == UINT64_C(0xffffffffffffffff)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LONG 8
+#endif
+
+#if defined(__hpux) // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 8
+#else
+
+// The list of the non-standard macros (the ones except ULLONG_MAX) is taken from cstdint.hpp
+#if defined(ULLONG_MAX)
+#define BOOST_ATOMIC_DETAIL_ULLONG_MAX ULLONG_MAX
+#elif defined(ULONG_LONG_MAX)
+#define BOOST_ATOMIC_DETAIL_ULLONG_MAX ULONG_LONG_MAX
+#elif defined(ULONGLONG_MAX)
+#define BOOST_ATOMIC_DETAIL_ULLONG_MAX ULONGLONG_MAX
+#elif defined(_LLONG_MAX) // strangely enough, this one seems to be holding the limit for the unsigned integer
+#define BOOST_ATOMIC_DETAIL_ULLONG_MAX _LLONG_MAX
+#endif
+
+#if (BOOST_ATOMIC_DETAIL_ULLONG_MAX + 0) == 0xff
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 1
+#elif (BOOST_ATOMIC_DETAIL_ULLONG_MAX + 0) == 0xffff
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 2
+#elif (BOOST_ATOMIC_DETAIL_ULLONG_MAX + 0) == 0xffffffff
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 4
+#elif (BOOST_ATOMIC_DETAIL_ULLONG_MAX + 0) == UINT64_C(0xffffffffffffffff)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 8
+#endif
+
+#endif // defined(__hpux)
+
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T)
+
+#include <wchar.h>
+#include <boost/cstdint.hpp>
+
+#if defined(_MSC_VER) && (_MSC_VER <= 1310 || defined(UNDER_CE) && _MSC_VER <= 1500)
+// MSVC 7.1 and MSVC 8 (arm) define WCHAR_MAX to a value not suitable for constant expressions
+#define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 2
+#elif (WCHAR_MAX + 0) == 0xff || (WCHAR_MAX + 0) == 0x7f
+#define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 1
+#elif (WCHAR_MAX + 0) == 0xffff || (WCHAR_MAX + 0) == 0x7fff
+#define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 2
+#elif (WCHAR_MAX + 0) == 0xffffffff || (WCHAR_MAX + 0) == 0x7fffffff
+#define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 4
+#elif (WCHAR_MAX + 0) == UINT64_C(0xffffffffffffffff) || (WCHAR_MAX + 0) == INT64_C(0x7fffffffffffffff)
+#define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 8
+#endif
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_SHORT) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_INT) ||\
+    !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LLONG) ||\
+    !defined(BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T)
+#error Boost.Atomic: Failed to determine builtin integer sizes, the target platform is not supported. Please, report to the developers (patches are welcome).
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_INT_SIZES_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/integral_conversions.hpp b/ThirdParty/boost/atomic/detail/integral_conversions.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a293d77229de8502b1341eec897d82ebae766876
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/integral_conversions.hpp
@@ -0,0 +1,105 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/integral_conversions.hpp
+ *
+ * This header defines sign/zero extension and truncation utilities for Boost.Atomic. The tools assume two's complement signed integer representation.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_INTEGRAL_CONVERSIONS_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_INTEGRAL_CONVERSIONS_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/bitwise_cast.hpp>
+#include <boost/atomic/detail/type_traits/integral_constant.hpp>
+#include <boost/atomic/detail/type_traits/is_signed.hpp>
+#include <boost/atomic/detail/type_traits/make_signed.hpp>
+#include <boost/atomic/detail/type_traits/make_unsigned.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< typename Output, typename Input >
+BOOST_FORCEINLINE Output zero_extend_impl(Input input, atomics::detail::true_type) BOOST_NOEXCEPT
+{
+    // Note: If we are casting with truncation or to the same-sized output, don't cause signed integer overflow by this chain of conversions
+    return atomics::detail::bitwise_cast< Output >(static_cast< typename atomics::detail::make_unsigned< Output >::type >(
+        static_cast< typename atomics::detail::make_unsigned< Input >::type >(input)));
+}
+
+template< typename Output, typename Input >
+BOOST_FORCEINLINE Output zero_extend_impl(Input input, atomics::detail::false_type) BOOST_NOEXCEPT
+{
+    return static_cast< Output >(static_cast< typename atomics::detail::make_unsigned< Input >::type >(input));
+}
+
+//! Zero-extends or truncates (wraps) input operand to fit in the output type
+template< typename Output, typename Input >
+BOOST_FORCEINLINE Output zero_extend(Input input) BOOST_NOEXCEPT
+{
+    return atomics::detail::zero_extend_impl< Output >(input, atomics::detail::integral_constant< bool, atomics::detail::is_signed< Output >::value >());
+}
+
+//! Truncates (wraps) input operand to fit in the output type
+template< typename Output, typename Input >
+BOOST_FORCEINLINE Output integral_truncate(Input input) BOOST_NOEXCEPT
+{
+    // zero_extend does the truncation
+    return atomics::detail::zero_extend< Output >(input);
+}
+
+template< typename Output, typename Input >
+BOOST_FORCEINLINE Output sign_extend_impl(Input input, atomics::detail::true_type) BOOST_NOEXCEPT
+{
+    return atomics::detail::integral_truncate< Output >(input);
+}
+
+template< typename Output, typename Input >
+BOOST_FORCEINLINE Output sign_extend_impl(Input input, atomics::detail::false_type) BOOST_NOEXCEPT
+{
+    return static_cast< Output >(atomics::detail::bitwise_cast< typename atomics::detail::make_signed< Input >::type >(input));
+}
+
+//! Sign-extends or truncates (wraps) input operand to fit in the output type
+template< typename Output, typename Input >
+BOOST_FORCEINLINE Output sign_extend(Input input) BOOST_NOEXCEPT
+{
+    return atomics::detail::sign_extend_impl< Output >(input, atomics::detail::integral_constant< bool, sizeof(Output) <= sizeof(Input) >());
+}
+
+//! Sign-extends or truncates (wraps) input operand to fit in the output type
+template< typename Output, typename Input >
+BOOST_FORCEINLINE Output integral_extend(Input input, atomics::detail::true_type) BOOST_NOEXCEPT
+{
+    return atomics::detail::sign_extend< Output >(input);
+}
+
+//! Zero-extends or truncates (wraps) input operand to fit in the output type
+template< typename Output, typename Input >
+BOOST_FORCEINLINE Output integral_extend(Input input, atomics::detail::false_type) BOOST_NOEXCEPT
+{
+    return atomics::detail::zero_extend< Output >(input);
+}
+
+//! Sign- or zero-extends or truncates (wraps) input operand to fit in the output type
+template< bool Signed, typename Output, typename Input >
+BOOST_FORCEINLINE Output integral_extend(Input input) BOOST_NOEXCEPT
+{
+    return atomics::detail::integral_extend< Output >(input, atomics::detail::integral_constant< bool, Signed >());
+}
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_INTEGRAL_CONVERSIONS_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/interlocked.hpp b/ThirdParty/boost/atomic/detail/interlocked.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..774354fb7f2f74e43260c2d6c9a996e805c301b4
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/interlocked.hpp
@@ -0,0 +1,522 @@
+#ifndef BOOST_ATOMIC_DETAIL_INTERLOCKED_HPP
+#define BOOST_ATOMIC_DETAIL_INTERLOCKED_HPP
+
+//  Copyright (c) 2009 Helge Bahmann
+//  Copyright (c) 2012 - 2014, 2017 Andrey Semashev
+//
+//  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)
+
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(_WIN32_WCE)
+
+#if _WIN32_WCE >= 0x600
+
+extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long );
+extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long );
+extern "C" long __cdecl _InterlockedExchange( long volatile *, long );
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) _InterlockedCompareExchange((long*)(dest), exchange, compare)
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) _InterlockedExchangeAdd((long*)(dest), (long)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) _InterlockedExchange((long*)(dest), (long)(newval))
+
+#else // _WIN32_WCE >= 0x600
+
+extern "C" long __cdecl InterlockedCompareExchange( long*, long, long );
+extern "C" long __cdecl InterlockedExchangeAdd( long*, long );
+extern "C" long __cdecl InterlockedExchange( long*, long );
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) InterlockedCompareExchange((long*)(dest), exchange, compare)
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) InterlockedExchangeAdd((long*)(dest), (long)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) InterlockedExchange((long*)(dest), (long)(newval))
+
+#endif // _WIN32_WCE >= 0x600
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE((long*)(dest), (long)(exchange), (long)(compare)))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, exchange) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE((long*)(dest), (long)(exchange)))
+
+#elif defined(_MSC_VER) && _MSC_VER >= 1310
+
+#if _MSC_VER < 1400
+
+extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long );
+extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long );
+extern "C" long __cdecl _InterlockedExchange( long volatile *, long );
+
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_InterlockedCompareExchange)
+#pragma intrinsic(_InterlockedExchangeAdd)
+#pragma intrinsic(_InterlockedExchange)
+#endif
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) _InterlockedCompareExchange((long*)(dest), exchange, compare)
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) _InterlockedExchangeAdd((long*)(dest), (long)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) _InterlockedExchange((long*)(dest), (long)(newval))
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE((long*)(dest), (long)(exchange), (long)(compare)))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, exchange) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE((long*)(dest), (long)(exchange)))
+
+#else // _MSC_VER < 1400
+
+#include <intrin.h>
+
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_InterlockedCompareExchange)
+#pragma intrinsic(_InterlockedExchangeAdd)
+#pragma intrinsic(_InterlockedExchange)
+#pragma intrinsic(_InterlockedAnd)
+#pragma intrinsic(_InterlockedOr)
+#pragma intrinsic(_InterlockedXor)
+#pragma intrinsic(_interlockedbittestandset)
+#pragma intrinsic(_interlockedbittestandreset)
+#endif
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) _InterlockedCompareExchange((long*)(dest), (long)(exchange), (long)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) _InterlockedExchangeAdd((long*)(dest), (long)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) _InterlockedExchange((long*)(dest), (long)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_AND(dest, arg) _InterlockedAnd((long*)(dest), (long)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_OR(dest, arg) _InterlockedOr((long*)(dest), (long)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_XOR(dest, arg) _InterlockedXor((long*)(dest), (long)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_BTS(dest, arg) _interlockedbittestandset((long*)(dest), (long)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_BTR(dest, arg) _interlockedbittestandreset((long*)(dest), (long)(arg))
+
+#if defined(_M_AMD64)
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_interlockedbittestandset64)
+#pragma intrinsic(_interlockedbittestandreset64)
+#endif
+
+#define BOOST_ATOMIC_INTERLOCKED_BTS64(dest, arg) _interlockedbittestandset64((__int64*)(dest), (__int64)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_BTR64(dest, arg) _interlockedbittestandreset64((__int64*)(dest), (__int64)(arg))
+#endif // defined(_M_AMD64)
+
+#if (defined(_M_IX86) && _M_IX86 >= 500) || defined(_M_AMD64) || defined(_M_IA64)
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_InterlockedCompareExchange64)
+#endif
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) _InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare))
+#endif
+
+#if _MSC_VER >= 1500 && defined(_M_AMD64)
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_InterlockedCompareExchange128)
+#endif
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE128(dest, exchange, compare) _InterlockedCompareExchange128((__int64*)(dest), ((const __int64*)(&exchange))[1], ((const __int64*)(&exchange))[0], (__int64*)(compare))
+#endif
+
+#if _MSC_VER >= 1600
+
+// MSVC 2010 and later provide intrinsics for 8 and 16 bit integers.
+// Note that for each bit count these macros must be either all defined or all not defined.
+// Otherwise atomic<> operations will be implemented inconsistently.
+
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_InterlockedCompareExchange8)
+#pragma intrinsic(_InterlockedExchangeAdd8)
+#pragma intrinsic(_InterlockedExchange8)
+#pragma intrinsic(_InterlockedAnd8)
+#pragma intrinsic(_InterlockedOr8)
+#pragma intrinsic(_InterlockedXor8)
+#endif
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8(dest, exchange, compare) _InterlockedCompareExchange8((char*)(dest), (char)(exchange), (char)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8(dest, addend) _InterlockedExchangeAdd8((char*)(dest), (char)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE8(dest, newval) _InterlockedExchange8((char*)(dest), (char)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_AND8(dest, arg) _InterlockedAnd8((char*)(dest), (char)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_OR8(dest, arg) _InterlockedOr8((char*)(dest), (char)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_XOR8(dest, arg) _InterlockedXor8((char*)(dest), (char)(arg))
+
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_InterlockedCompareExchange16)
+#pragma intrinsic(_InterlockedExchangeAdd16)
+#pragma intrinsic(_InterlockedExchange16)
+#pragma intrinsic(_InterlockedAnd16)
+#pragma intrinsic(_InterlockedOr16)
+#pragma intrinsic(_InterlockedXor16)
+#endif
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16(dest, exchange, compare) _InterlockedCompareExchange16((short*)(dest), (short)(exchange), (short)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16(dest, addend) _InterlockedExchangeAdd16((short*)(dest), (short)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE16(dest, newval) _InterlockedExchange16((short*)(dest), (short)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_AND16(dest, arg) _InterlockedAnd16((short*)(dest), (short)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_OR16(dest, arg) _InterlockedOr16((short*)(dest), (short)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_XOR16(dest, arg) _InterlockedXor16((short*)(dest), (short)(arg))
+
+#endif // _MSC_VER >= 1600
+
+#if defined(_M_AMD64) || defined(_M_IA64)
+
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_InterlockedExchangeAdd64)
+#pragma intrinsic(_InterlockedExchange64)
+#pragma intrinsic(_InterlockedAnd64)
+#pragma intrinsic(_InterlockedOr64)
+#pragma intrinsic(_InterlockedXor64)
+#endif
+
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) _InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) _InterlockedExchange64((__int64*)(dest), (__int64)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_AND64(dest, arg) _InterlockedAnd64((__int64*)(dest), (__int64)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_OR64(dest, arg) _InterlockedOr64((__int64*)(dest), (__int64)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_XOR64(dest, arg) _InterlockedXor64((__int64*)(dest), (__int64)(arg))
+
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_InterlockedCompareExchangePointer)
+#pragma intrinsic(_InterlockedExchangePointer)
+#endif
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) _InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) _InterlockedExchangePointer((void**)(dest), (void*)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64((long*)(dest), byte_offset))
+
+#elif defined(_M_IX86)
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)_InterlockedCompareExchange((long*)(dest), (long)(exchange), (long)(compare)))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) ((void*)_InterlockedExchange((long*)(dest), (long)(newval)))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD((long*)(dest), byte_offset))
+
+#endif
+
+#if _MSC_VER >= 1700 && (defined(_M_ARM) || defined(_M_ARM64))
+
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_InterlockedExchangeAdd64)
+#pragma intrinsic(_InterlockedExchange64)
+#pragma intrinsic(_InterlockedAnd64)
+#pragma intrinsic(_InterlockedOr64)
+#pragma intrinsic(_InterlockedXor64)
+#endif
+
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) _InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) _InterlockedExchange64((__int64*)(dest), (__int64)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_AND64(dest, arg) _InterlockedAnd64((__int64*)(dest), (__int64)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_OR64(dest, arg) _InterlockedOr64((__int64*)(dest), (__int64)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_XOR64(dest, arg) _InterlockedXor64((__int64*)(dest), (__int64)(arg))
+
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_InterlockedCompareExchange8_nf)
+#pragma intrinsic(_InterlockedCompareExchange8_acq)
+#pragma intrinsic(_InterlockedCompareExchange8_rel)
+#pragma intrinsic(_InterlockedCompareExchange16_nf)
+#pragma intrinsic(_InterlockedCompareExchange16_acq)
+#pragma intrinsic(_InterlockedCompareExchange16_rel)
+#pragma intrinsic(_InterlockedCompareExchange_nf)
+#pragma intrinsic(_InterlockedCompareExchange_acq)
+#pragma intrinsic(_InterlockedCompareExchange_rel)
+#pragma intrinsic(_InterlockedCompareExchange64)
+#pragma intrinsic(_InterlockedCompareExchange64_nf)
+#pragma intrinsic(_InterlockedCompareExchange64_acq)
+#pragma intrinsic(_InterlockedCompareExchange64_rel)
+#pragma intrinsic(_InterlockedCompareExchangePointer)
+#pragma intrinsic(_InterlockedCompareExchangePointer_nf)
+#pragma intrinsic(_InterlockedCompareExchangePointer_acq)
+#pragma intrinsic(_InterlockedCompareExchangePointer_rel)
+#endif
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_RELAXED(dest, exchange, compare) _InterlockedCompareExchange8_nf((char*)(dest), (char)(exchange), (char)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_ACQUIRE(dest, exchange, compare) _InterlockedCompareExchange8_acq((char*)(dest), (char)(exchange), (char)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_RELEASE(dest, exchange, compare) _InterlockedCompareExchange8_rel((char*)(dest), (char)(exchange), (char)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_RELAXED(dest, exchange, compare) _InterlockedCompareExchange16_nf((short*)(dest), (short)(exchange), (short)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_ACQUIRE(dest, exchange, compare) _InterlockedCompareExchange16_acq((short*)(dest), (short)(exchange), (short)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_RELEASE(dest, exchange, compare) _InterlockedCompareExchange16_rel((short*)(dest), (short)(exchange), (short)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_RELAXED(dest, exchange, compare) _InterlockedCompareExchange_nf((long*)(dest), (long)(exchange), (long)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_ACQUIRE(dest, exchange, compare) _InterlockedCompareExchange_acq((long*)(dest), (long)(exchange), (long)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_RELEASE(dest, exchange, compare) _InterlockedCompareExchange_rel((long*)(dest), (long)(exchange), (long)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) _InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_RELAXED(dest, exchange, compare) _InterlockedCompareExchange64_nf((__int64*)(dest), (__int64)(exchange), (__int64)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_ACQUIRE(dest, exchange, compare) _InterlockedCompareExchange64_acq((__int64*)(dest), (__int64)(exchange), (__int64)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_RELEASE(dest, exchange, compare) _InterlockedCompareExchange64_rel((__int64*)(dest), (__int64)(exchange), (__int64)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) _InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER_RELAXED(dest, exchange, compare) _InterlockedCompareExchangePointer_nf((void**)(dest), (void*)(exchange), (void*)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER_ACQUIRE(dest, exchange, compare) _InterlockedCompareExchangePointer_acq((void**)(dest), (void*)(exchange), (void*)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER_RELEASE(dest, exchange, compare) _InterlockedCompareExchangePointer_rel((void**)(dest), (void*)(exchange), (void*)(compare))
+
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_InterlockedExchangeAdd8_nf)
+#pragma intrinsic(_InterlockedExchangeAdd8_acq)
+#pragma intrinsic(_InterlockedExchangeAdd8_rel)
+#pragma intrinsic(_InterlockedExchangeAdd16_nf)
+#pragma intrinsic(_InterlockedExchangeAdd16_acq)
+#pragma intrinsic(_InterlockedExchangeAdd16_rel)
+#pragma intrinsic(_InterlockedExchangeAdd_nf)
+#pragma intrinsic(_InterlockedExchangeAdd_acq)
+#pragma intrinsic(_InterlockedExchangeAdd_rel)
+#pragma intrinsic(_InterlockedExchangeAdd64_nf)
+#pragma intrinsic(_InterlockedExchangeAdd64_acq)
+#pragma intrinsic(_InterlockedExchangeAdd64_rel)
+#endif
+
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_RELAXED(dest, addend) _InterlockedExchangeAdd8_nf((char*)(dest), (char)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_ACQUIRE(dest, addend) _InterlockedExchangeAdd8_acq((char*)(dest), (char)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_RELEASE(dest, addend) _InterlockedExchangeAdd8_rel((char*)(dest), (char)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_RELAXED(dest, addend) _InterlockedExchangeAdd16_nf((short*)(dest), (short)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_ACQUIRE(dest, addend) _InterlockedExchangeAdd16_acq((short*)(dest), (short)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_RELEASE(dest, addend) _InterlockedExchangeAdd16_rel((short*)(dest), (short)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELAXED(dest, addend) _InterlockedExchangeAdd_nf((long*)(dest), (long)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_ACQUIRE(dest, addend) _InterlockedExchangeAdd_acq((long*)(dest), (long)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELEASE(dest, addend) _InterlockedExchangeAdd_rel((long*)(dest), (long)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELAXED(dest, addend) _InterlockedExchangeAdd64_nf((__int64*)(dest), (__int64)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_ACQUIRE(dest, addend) _InterlockedExchangeAdd64_acq((__int64*)(dest), (__int64)(addend))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELEASE(dest, addend) _InterlockedExchangeAdd64_rel((__int64*)(dest), (__int64)(addend))
+
+#if defined(_M_ARM64)
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64((__int64*)(dest), byte_offset))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER_RELAXED(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELAXED((__int64*)(dest), byte_offset))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER_ACQUIRE(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_ACQUIRE((__int64*)(dest), byte_offset))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER_RELEASE(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELEASE((__int64*)(dest), byte_offset))
+#else
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD((long*)(dest), byte_offset))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER_RELAXED(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELAXED((long*)(dest), byte_offset))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER_ACQUIRE(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_ACQUIRE((long*)(dest), byte_offset))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER_RELEASE(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELEASE((long*)(dest), byte_offset))
+#endif
+
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_InterlockedExchange8_nf)
+#pragma intrinsic(_InterlockedExchange8_acq)
+#pragma intrinsic(_InterlockedExchange16_nf)
+#pragma intrinsic(_InterlockedExchange16_acq)
+#pragma intrinsic(_InterlockedExchange_nf)
+#pragma intrinsic(_InterlockedExchange_acq)
+#pragma intrinsic(_InterlockedExchange64_nf)
+#pragma intrinsic(_InterlockedExchange64_acq)
+#pragma intrinsic(_InterlockedExchangePointer)
+#pragma intrinsic(_InterlockedExchangePointer_nf)
+#pragma intrinsic(_InterlockedExchangePointer_acq)
+#if _MSC_VER >= 1800
+#pragma intrinsic(_InterlockedExchange8_rel)
+#pragma intrinsic(_InterlockedExchange16_rel)
+#pragma intrinsic(_InterlockedExchange_rel)
+#pragma intrinsic(_InterlockedExchange64_rel)
+#pragma intrinsic(_InterlockedExchangePointer_rel)
+#endif
+#endif
+
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_RELAXED(dest, newval) _InterlockedExchange8_nf((char*)(dest), (char)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_ACQUIRE(dest, newval) _InterlockedExchange8_acq((char*)(dest), (char)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_RELAXED(dest, newval) _InterlockedExchange16_nf((short*)(dest), (short)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_ACQUIRE(dest, newval) _InterlockedExchange16_acq((short*)(dest), (short)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_RELAXED(dest, newval) _InterlockedExchange_nf((long*)(dest), (long)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ACQUIRE(dest, newval) _InterlockedExchange_acq((long*)(dest), (long)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_RELAXED(dest, newval) _InterlockedExchange64_nf((__int64*)(dest), (__int64)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_ACQUIRE(dest, newval) _InterlockedExchange64_acq((__int64*)(dest), (__int64)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) _InterlockedExchangePointer((void**)(dest), (void*)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER_RELAXED(dest, newval) _InterlockedExchangePointer_nf((void**)(dest), (void*)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER_ACQUIRE(dest, newval) _InterlockedExchangePointer_acq((void**)(dest), (void*)(newval))
+
+#if _MSC_VER >= 1800
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_RELEASE(dest, newval) _InterlockedExchange8_rel((char*)(dest), (char)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_RELEASE(dest, newval) _InterlockedExchange16_rel((short*)(dest), (short)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_RELEASE(dest, newval) _InterlockedExchange_rel((long*)(dest), (long)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_RELEASE(dest, newval) _InterlockedExchange64_rel((__int64*)(dest), (__int64)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER_RELEASE(dest, newval) _InterlockedExchangePointer_rel((void**)(dest), (void*)(newval))
+#else
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_RELEASE(dest, newval) BOOST_ATOMIC_INTERLOCKED_EXCHANGE8(dest, newval)
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_RELEASE(dest, newval) BOOST_ATOMIC_INTERLOCKED_EXCHANGE16(dest, newval)
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_RELEASE(dest, newval) BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval)
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_RELEASE(dest, newval) BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval)
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER_RELEASE(dest, newval) BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval)
+#endif
+
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_InterlockedAnd8_nf)
+#pragma intrinsic(_InterlockedAnd8_acq)
+#pragma intrinsic(_InterlockedAnd8_rel)
+#pragma intrinsic(_InterlockedAnd16_nf)
+#pragma intrinsic(_InterlockedAnd16_acq)
+#pragma intrinsic(_InterlockedAnd16_rel)
+#pragma intrinsic(_InterlockedAnd_nf)
+#pragma intrinsic(_InterlockedAnd_acq)
+#pragma intrinsic(_InterlockedAnd_rel)
+#pragma intrinsic(_InterlockedAnd64_nf)
+#pragma intrinsic(_InterlockedAnd64_acq)
+#pragma intrinsic(_InterlockedAnd64_rel)
+#endif
+
+#define BOOST_ATOMIC_INTERLOCKED_AND8_RELAXED(dest, arg) _InterlockedAnd8_nf((char*)(dest), (char)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_AND8_ACQUIRE(dest, arg) _InterlockedAnd8_acq((char*)(dest), (char)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_AND8_RELEASE(dest, arg) _InterlockedAnd8_rel((char*)(dest), (char)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_AND16_RELAXED(dest, arg) _InterlockedAnd16_nf((short*)(dest), (short)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_AND16_ACQUIRE(dest, arg) _InterlockedAnd16_acq((short*)(dest), (short)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_AND16_RELEASE(dest, arg) _InterlockedAnd16_rel((short*)(dest), (short)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_AND_RELAXED(dest, arg) _InterlockedAnd_nf((long*)(dest), (long)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_AND_ACQUIRE(dest, arg) _InterlockedAnd_acq((long*)(dest), (long)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_AND_RELEASE(dest, arg) _InterlockedAnd_rel((long*)(dest), (long)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_AND64_RELAXED(dest, arg) _InterlockedAnd64_nf((__int64*)(dest), (__int64)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_AND64_ACQUIRE(dest, arg) _InterlockedAnd64_acq((__int64*)(dest), (__int64)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_AND64_RELEASE(dest, arg) _InterlockedAnd64_rel((__int64*)(dest), (__int64)(arg))
+
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_InterlockedOr8_nf)
+#pragma intrinsic(_InterlockedOr8_acq)
+#pragma intrinsic(_InterlockedOr8_rel)
+#pragma intrinsic(_InterlockedOr16_nf)
+#pragma intrinsic(_InterlockedOr16_acq)
+#pragma intrinsic(_InterlockedOr16_rel)
+#pragma intrinsic(_InterlockedOr_nf)
+#pragma intrinsic(_InterlockedOr_acq)
+#pragma intrinsic(_InterlockedOr_rel)
+#pragma intrinsic(_InterlockedOr64_nf)
+#pragma intrinsic(_InterlockedOr64_acq)
+#pragma intrinsic(_InterlockedOr64_rel)
+#endif
+
+#define BOOST_ATOMIC_INTERLOCKED_OR8_RELAXED(dest, arg) _InterlockedOr8_nf((char*)(dest), (char)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_OR8_ACQUIRE(dest, arg) _InterlockedOr8_acq((char*)(dest), (char)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_OR8_RELEASE(dest, arg) _InterlockedOr8_rel((char*)(dest), (char)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_OR16_RELAXED(dest, arg) _InterlockedOr16_nf((short*)(dest), (short)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_OR16_ACQUIRE(dest, arg) _InterlockedOr16_acq((short*)(dest), (short)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_OR16_RELEASE(dest, arg) _InterlockedOr16_rel((short*)(dest), (short)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_OR_RELAXED(dest, arg) _InterlockedOr_nf((long*)(dest), (long)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_OR_ACQUIRE(dest, arg) _InterlockedOr_acq((long*)(dest), (long)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_OR_RELEASE(dest, arg) _InterlockedOr_rel((long*)(dest), (long)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_OR64_RELAXED(dest, arg) _InterlockedOr64_nf((__int64*)(dest), (__int64)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_OR64_ACQUIRE(dest, arg) _InterlockedOr64_acq((__int64*)(dest), (__int64)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_OR64_RELEASE(dest, arg) _InterlockedOr64_rel((__int64*)(dest), (__int64)(arg))
+
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_InterlockedXor8_nf)
+#pragma intrinsic(_InterlockedXor8_acq)
+#pragma intrinsic(_InterlockedXor8_rel)
+#pragma intrinsic(_InterlockedXor16_nf)
+#pragma intrinsic(_InterlockedXor16_acq)
+#pragma intrinsic(_InterlockedXor16_rel)
+#pragma intrinsic(_InterlockedXor_nf)
+#pragma intrinsic(_InterlockedXor_acq)
+#pragma intrinsic(_InterlockedXor_rel)
+#pragma intrinsic(_InterlockedXor64_nf)
+#pragma intrinsic(_InterlockedXor64_acq)
+#pragma intrinsic(_InterlockedXor64_rel)
+#endif
+
+#define BOOST_ATOMIC_INTERLOCKED_XOR8_RELAXED(dest, arg) _InterlockedXor8_nf((char*)(dest), (char)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_XOR8_ACQUIRE(dest, arg) _InterlockedXor8_acq((char*)(dest), (char)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_XOR8_RELEASE(dest, arg) _InterlockedXor8_rel((char*)(dest), (char)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_XOR16_RELAXED(dest, arg) _InterlockedXor16_nf((short*)(dest), (short)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_XOR16_ACQUIRE(dest, arg) _InterlockedXor16_acq((short*)(dest), (short)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_XOR16_RELEASE(dest, arg) _InterlockedXor16_rel((short*)(dest), (short)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_XOR_RELAXED(dest, arg) _InterlockedXor_nf((long*)(dest), (long)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_XOR_ACQUIRE(dest, arg) _InterlockedXor_acq((long*)(dest), (long)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_XOR_RELEASE(dest, arg) _InterlockedXor_rel((long*)(dest), (long)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_XOR64_RELAXED(dest, arg) _InterlockedXor64_nf((__int64*)(dest), (__int64)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_XOR64_ACQUIRE(dest, arg) _InterlockedXor64_acq((__int64*)(dest), (__int64)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_XOR64_RELEASE(dest, arg) _InterlockedXor64_rel((__int64*)(dest), (__int64)(arg))
+
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_interlockedbittestandset_nf)
+#pragma intrinsic(_interlockedbittestandset_acq)
+#pragma intrinsic(_interlockedbittestandset_rel)
+#endif
+
+#define BOOST_ATOMIC_INTERLOCKED_BTS_RELAXED(dest, arg) _interlockedbittestandset_nf((long*)(dest), (long)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_BTS_ACQUIRE(dest, arg) _interlockedbittestandset_acq((long*)(dest), (long)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_BTS_RELEASE(dest, arg) _interlockedbittestandset_rel((long*)(dest), (long)(arg))
+
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_interlockedbittestandreset_nf)
+#pragma intrinsic(_interlockedbittestandreset_acq)
+#pragma intrinsic(_interlockedbittestandreset_rel)
+#endif
+
+#define BOOST_ATOMIC_INTERLOCKED_BTR_RELAXED(dest, arg) _interlockedbittestandreset_nf((long*)(dest), (long)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_BTR_ACQUIRE(dest, arg) _interlockedbittestandreset_acq((long*)(dest), (long)(arg))
+#define BOOST_ATOMIC_INTERLOCKED_BTR_RELEASE(dest, arg) _interlockedbittestandreset_rel((long*)(dest), (long)(arg))
+
+#endif // _MSC_VER >= 1700 && defined(_M_ARM)
+
+#endif // _MSC_VER < 1400
+
+#else // defined(_MSC_VER) && _MSC_VER >= 1310
+
+#if defined(BOOST_USE_WINDOWS_H)
+
+#include <windows.h>
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) InterlockedCompareExchange((long*)(dest), (long)(exchange), (long)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) InterlockedExchange((long*)(dest), (long)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) InterlockedExchangeAdd((long*)(dest), (long)(addend))
+
+#if defined(_WIN64)
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) InterlockedExchange64((__int64*)(dest), (__int64)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend))
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) InterlockedExchangePointer((void**)(dest), (void*)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, byte_offset))
+
+#else // defined(_WIN64)
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, byte_offset))
+
+#endif // defined(_WIN64)
+
+#else // defined(BOOST_USE_WINDOWS_H)
+
+#if defined(__MINGW64__)
+#define BOOST_ATOMIC_INTERLOCKED_IMPORT
+#else
+#define BOOST_ATOMIC_INTERLOCKED_IMPORT __declspec(dllimport)
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+extern "C" {
+
+BOOST_ATOMIC_INTERLOCKED_IMPORT long __stdcall InterlockedCompareExchange(long volatile*, long, long);
+BOOST_ATOMIC_INTERLOCKED_IMPORT long __stdcall InterlockedExchange(long volatile*, long);
+BOOST_ATOMIC_INTERLOCKED_IMPORT long __stdcall InterlockedExchangeAdd(long volatile*, long);
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) boost::atomics::detail::InterlockedCompareExchange((long*)(dest), (long)(exchange), (long)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) boost::atomics::detail::InterlockedExchange((long*)(dest), (long)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) boost::atomics::detail::InterlockedExchangeAdd((long*)(dest), (long)(addend))
+
+#if defined(_WIN64)
+
+BOOST_ATOMIC_INTERLOCKED_IMPORT __int64 __stdcall InterlockedCompareExchange64(__int64 volatile*, __int64, __int64);
+BOOST_ATOMIC_INTERLOCKED_IMPORT __int64 __stdcall InterlockedExchange64(__int64 volatile*, __int64);
+BOOST_ATOMIC_INTERLOCKED_IMPORT __int64 __stdcall InterlockedExchangeAdd64(__int64 volatile*, __int64);
+
+BOOST_ATOMIC_INTERLOCKED_IMPORT void* __stdcall InterlockedCompareExchangePointer(void* volatile *, void*, void*);
+BOOST_ATOMIC_INTERLOCKED_IMPORT void* __stdcall InterlockedExchangePointer(void* volatile *, void*);
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) boost::atomics::detail::InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) boost::atomics::detail::InterlockedExchange64((__int64*)(dest), (__int64)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) boost::atomics::detail::InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend))
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) boost::atomics::detail::InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) boost::atomics::detail::InterlockedExchangePointer((void**)(dest), (void*)(newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, byte_offset))
+
+#else // defined(_WIN64)
+
+#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval))
+#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, byte_offset))
+
+#endif // defined(_WIN64)
+
+} // extern "C"
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#undef BOOST_ATOMIC_INTERLOCKED_IMPORT
+
+#endif // defined(BOOST_USE_WINDOWS_H)
+
+#endif // defined(_MSC_VER)
+
+#endif
diff --git a/ThirdParty/boost/atomic/detail/intptr.hpp b/ThirdParty/boost/atomic/detail/intptr.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..301233a3e104aced6282cd7b42673d19528b48fb
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/intptr.hpp
@@ -0,0 +1,43 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2020 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/intptr.hpp
+ *
+ * This header defines (u)intptr_t types.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_INTPTR_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_INTPTR_HPP_INCLUDED_
+
+#include <boost/cstdint.hpp>
+#if defined(BOOST_HAS_INTPTR_T)
+#include <cstddef>
+#endif
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+#if !defined(BOOST_HAS_INTPTR_T)
+using boost::uintptr_t;
+using boost::intptr_t;
+#else
+typedef std::size_t uintptr_t;
+typedef std::ptrdiff_t intptr_t;
+#endif
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_INTPTR_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/link.hpp b/ThirdParty/boost/atomic/detail/link.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4f522acbcf9ff0d99ec44cb3902344bf5a84e102
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/link.hpp
@@ -0,0 +1,58 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2012 Hartmut Kaiser
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/config.hpp
+ *
+ * This header defines macros for linking with compiled library of Boost.Atomic
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_LINK_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_LINK_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//  Set up dll import/export options
+#if (defined(BOOST_ATOMIC_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && \
+    !defined(BOOST_ATOMIC_STATIC_LINK)
+
+#if defined(BOOST_ATOMIC_SOURCE)
+#define BOOST_ATOMIC_DECL BOOST_SYMBOL_EXPORT
+#define BOOST_ATOMIC_BUILD_DLL
+#else
+#define BOOST_ATOMIC_DECL BOOST_SYMBOL_IMPORT
+#endif
+
+#endif // building a shared library
+
+#ifndef BOOST_ATOMIC_DECL
+#define BOOST_ATOMIC_DECL
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//  Auto library naming
+#if !defined(BOOST_ATOMIC_SOURCE) && !defined(BOOST_ALL_NO_LIB) && \
+    !defined(BOOST_ATOMIC_NO_LIB)
+
+#define BOOST_LIB_NAME boost_atomic
+
+// tell the auto-link code to select a dll when required:
+#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ATOMIC_DYN_LINK)
+#define BOOST_DYN_LINK
+#endif
+
+#include <boost/config/auto_link.hpp>
+
+#endif  // auto-linking disabled
+
+#endif
diff --git a/ThirdParty/boost/atomic/detail/lock_pool.hpp b/ThirdParty/boost/atomic/detail/lock_pool.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f0f67699ba9538ddecd2640509524401d657fbf5
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/lock_pool.hpp
@@ -0,0 +1,63 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2011 Helge Bahmann
+ * Copyright (c) 2013-2014, 2020 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/lock_pool.hpp
+ *
+ * This header contains declaration of the lock pool used to emulate atomic ops.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_LOCK_POOL_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_LOCK_POOL_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/link.hpp>
+#include <boost/atomic/detail/intptr.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+namespace lock_pool {
+
+BOOST_ATOMIC_DECL void* lock(atomics::detail::uintptr_t ptr) BOOST_NOEXCEPT;
+BOOST_ATOMIC_DECL void unlock(void* p) BOOST_NOEXCEPT;
+
+BOOST_ATOMIC_DECL void thread_fence() BOOST_NOEXCEPT;
+BOOST_ATOMIC_DECL void signal_fence() BOOST_NOEXCEPT;
+
+template< std::size_t Alignment >
+class scoped_lock
+{
+private:
+    void* m_lock;
+
+public:
+    explicit scoped_lock(const volatile void* addr) BOOST_NOEXCEPT :
+        m_lock(lock_pool::lock(((atomics::detail::uintptr_t)addr) / Alignment))
+    {
+    }
+    ~scoped_lock() BOOST_NOEXCEPT
+    {
+        lock_pool::unlock(m_lock);
+    }
+
+    BOOST_DELETED_FUNCTION(scoped_lock(scoped_lock const&))
+    BOOST_DELETED_FUNCTION(scoped_lock& operator=(scoped_lock const&))
+};
+
+} // namespace lock_pool
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_LOCK_POOL_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/memory_order_utils.hpp b/ThirdParty/boost/atomic/detail/memory_order_utils.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9a6871b0c889d469027a670b9f77fda5acf15a51
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/memory_order_utils.hpp
@@ -0,0 +1,44 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2020 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/memory_order_utils.hpp
+ *
+ * This header contains utilities related to memory order constants.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_MEMORY_ORDER_UTILS_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_MEMORY_ORDER_UTILS_HPP_INCLUDED_
+
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+BOOST_FORCEINLINE BOOST_CONSTEXPR memory_order deduce_failure_order(memory_order order) BOOST_NOEXCEPT
+{
+    return order == memory_order_acq_rel ? memory_order_acquire : (order == memory_order_release ? memory_order_relaxed : order);
+}
+
+BOOST_FORCEINLINE BOOST_CONSTEXPR bool cas_failure_order_must_not_be_stronger_than_success_order(memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+{
+    // 15 == (memory_order_seq_cst | memory_order_consume), see memory_order.hpp
+    // Given the enum values we can test the strength of memory order requirements with this single condition.
+    return (static_cast< unsigned int >(failure_order) & 15u) <= (static_cast< unsigned int >(success_order) & 15u);
+}
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_MEMORY_ORDER_UTILS_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/operations.hpp b/ThirdParty/boost/atomic/detail/operations.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d81399a8e3ffcb545dfb84bf1a335a643f83b0ab
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/operations.hpp
@@ -0,0 +1,24 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/operations.hpp
+ *
+ * This header defines atomic operations, including the emulated version.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPERATIONS_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPERATIONS_HPP_INCLUDED_
+
+#include <boost/atomic/detail/operations_lockfree.hpp>
+#include <boost/atomic/detail/ops_emulated.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_OPERATIONS_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/operations_fwd.hpp b/ThirdParty/boost/atomic/detail/operations_fwd.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e64bfb81718e89beda80189249c796cc3a44fe3a
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/operations_fwd.hpp
@@ -0,0 +1,38 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/operations_fwd.hpp
+ *
+ * This header contains forward declaration of the \c operations template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPERATIONS_FWD_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPERATIONS_FWD_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< std::size_t Size, std::size_t Alignment, bool Signed >
+struct emulated_operations;
+
+template< std::size_t Size, bool Signed >
+struct operations;
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_OPERATIONS_FWD_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/operations_lockfree.hpp b/ThirdParty/boost/atomic/detail/operations_lockfree.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..62b45836b5f33e08ca80befc327184b8ca7f8636
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/operations_lockfree.hpp
@@ -0,0 +1,30 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/operations_lockfree.hpp
+ *
+ * This header defines lockfree atomic operations.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPERATIONS_LOCKFREE_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPERATIONS_LOCKFREE_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/platform.hpp>
+
+#if !defined(BOOST_ATOMIC_EMULATED)
+#include BOOST_ATOMIC_DETAIL_BACKEND_HEADER(boost/atomic/detail/ops_)
+#else
+#include <boost/atomic/detail/operations_fwd.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_OPERATIONS_LOCKFREE_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_cas_based.hpp b/ThirdParty/boost/atomic/detail/ops_cas_based.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..17bf270244f4b60dda8a08660ac9f0671b35f1ed
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_cas_based.hpp
@@ -0,0 +1,107 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_cas_based.hpp
+ *
+ * This header contains CAS-based implementation of the \c operations template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_CAS_BASED_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_CAS_BASED_HPP_INCLUDED_
+
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< typename Base >
+struct cas_based_exchange :
+    public Base
+{
+    typedef typename Base::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_val;
+        atomics::detail::non_atomic_load(storage, old_val);
+        while (!Base::compare_exchange_weak(storage, old_val, v, order, memory_order_relaxed)) {}
+        return old_val;
+    }
+};
+
+template< typename Base >
+struct cas_based_operations :
+    public Base
+{
+    typedef typename Base::storage_type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_val;
+        atomics::detail::non_atomic_load(storage, old_val);
+        while (!Base::compare_exchange_weak(storage, old_val, old_val + v, order, memory_order_relaxed)) {}
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_val;
+        atomics::detail::non_atomic_load(storage, old_val);
+        while (!Base::compare_exchange_weak(storage, old_val, old_val - v, order, memory_order_relaxed)) {}
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_val;
+        atomics::detail::non_atomic_load(storage, old_val);
+        while (!Base::compare_exchange_weak(storage, old_val, old_val & v, order, memory_order_relaxed)) {}
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_val;
+        atomics::detail::non_atomic_load(storage, old_val);
+        while (!Base::compare_exchange_weak(storage, old_val, old_val | v, order, memory_order_relaxed)) {}
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_val;
+        atomics::detail::non_atomic_load(storage, old_val);
+        while (!Base::compare_exchange_weak(storage, old_val, old_val ^ v, order, memory_order_relaxed)) {}
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!Base::exchange(storage, (storage_type)1, order);
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        Base::store(storage, (storage_type)0, order);
+    }
+};
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_CAS_BASED_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_emulated.hpp b/ThirdParty/boost/atomic/detail/ops_emulated.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e6de0bb8417aa7d72d21134e94fbd732982a3ae5
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_emulated.hpp
@@ -0,0 +1,183 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2014, 2020 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_emulated.hpp
+ *
+ * This header contains lock pool-based implementation of the \c operations template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_EMULATED_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_EMULATED_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/operations_fwd.hpp>
+#include <boost/atomic/detail/lock_pool.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< std::size_t Size, std::size_t Alignment, bool = Alignment >= storage_traits< Size >::native_alignment >
+struct base_emulated_operations
+{
+    typedef typename storage_traits< Size >::type storage_type;
+};
+
+template< std::size_t Size, std::size_t Alignment >
+struct base_emulated_operations< Size, Alignment, false >
+{
+    typedef buffer_storage< Size, Alignment > storage_type;
+};
+
+template< std::size_t Size, std::size_t Alignment, bool Signed >
+struct emulated_operations :
+    public base_emulated_operations< Size, Alignment >
+{
+    typedef base_emulated_operations< Size, Alignment > base_type;
+
+    // Define storage_type to have alignment not greater than Alignment. This will allow operations to work with value_types
+    // that possibly have weaker alignment requirements than storage_traits< Size >::type would. This is important for atomic_ref<>.
+    // atomic<> will allow higher alignment requirement than its value_type.
+    // Note that storage_type should be an integral type, if possible, so that arithmetic and bitwise operations are possible.
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = Alignment >= storage_traits< Size >::alignment ? storage_traits< Size >::alignment : Alignment;
+
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+    static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false;
+
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = false;
+
+    typedef lock_pool::scoped_lock< storage_alignment > scoped_lock;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        scoped_lock lock(&storage);
+        const_cast< storage_type& >(storage) = v;
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        scoped_lock lock(&storage);
+        return const_cast< storage_type const& >(storage);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        storage_type old_val = s;
+        s += v;
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        storage_type old_val = s;
+        s -= v;
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        storage_type old_val = s;
+        s = v;
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        storage_type old_val = s;
+        const bool res = old_val == expected;
+        if (res)
+            s = desired;
+        expected = old_val;
+
+        return res;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
+    {
+        // Note: This function is the exact copy of compare_exchange_strong. The reason we're not just forwarding the call
+        // is that MSVC-12 ICEs in this case.
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        storage_type old_val = s;
+        const bool res = old_val == expected;
+        if (res)
+            s = desired;
+        expected = old_val;
+
+        return res;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        storage_type old_val = s;
+        s &= v;
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        storage_type old_val = s;
+        s |= v;
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type& s = const_cast< storage_type& >(storage);
+        scoped_lock lock(&storage);
+        storage_type old_val = s;
+        s ^= v;
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!exchange(storage, (storage_type)1, order);
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        store(storage, (storage_type)0, order);
+    }
+};
+
+template< std::size_t Size, bool Signed >
+struct operations :
+    public emulated_operations< Size, storage_traits< Size >::alignment, Signed >
+{
+};
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_EMULATED_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_extending_cas_based.hpp b/ThirdParty/boost/atomic/detail/ops_extending_cas_based.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..14fad35173ff8c24144635970165f116b204200f
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_extending_cas_based.hpp
@@ -0,0 +1,69 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_extending_cas_based.hpp
+ *
+ * This header contains a boilerplate of the \c operations template implementation that requires sign/zero extension in arithmetic operations.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_EXTENDING_CAS_BASED_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_EXTENDING_CAS_BASED_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/integral_conversions.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< typename Base, std::size_t Size, bool Signed >
+struct extending_cas_based_operations :
+    public Base
+{
+    typedef typename Base::storage_type storage_type;
+    typedef typename storage_traits< Size >::type emulated_storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_val;
+        atomics::detail::non_atomic_load(storage, old_val);
+        storage_type new_val;
+        do
+        {
+            new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val + v));
+        }
+        while (!Base::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
+        return old_val;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type old_val;
+        atomics::detail::non_atomic_load(storage, old_val);
+        storage_type new_val;
+        do
+        {
+            new_val = atomics::detail::integral_extend< Signed, storage_type >(static_cast< emulated_storage_type >(old_val - v));
+        }
+        while (!Base::compare_exchange_weak(storage, old_val, new_val, order, memory_order_relaxed));
+        return old_val;
+    }
+};
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_EXTENDING_CAS_BASED_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_gcc_alpha.hpp b/ThirdParty/boost/atomic/detail/ops_gcc_alpha.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d62e7a6ff889063ebbc61a39c905fabbe4a557df
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_gcc_alpha.hpp
@@ -0,0 +1,876 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_gcc_alpha.hpp
+ *
+ * This header contains implementation of the \c operations template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/operations_fwd.hpp>
+#include <boost/atomic/capabilities.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+/*
+  Refer to http://h71000.www7.hp.com/doc/82final/5601/5601pro_004.html
+  (HP OpenVMS systems documentation) and the Alpha Architecture Reference Manual.
+ */
+
+/*
+    NB: The most natural thing would be to write the increment/decrement
+    operators along the following lines:
+
+    __asm__ __volatile__
+    (
+        "1: ldl_l %0,%1 \n"
+        "addl %0,1,%0 \n"
+        "stl_c %0,%1 \n"
+        "beq %0,1b\n"
+        : "=&b" (tmp)
+        : "m" (value)
+        : "cc"
+    );
+
+    However according to the comments on the HP website and matching
+    comments in the Linux kernel sources this defies branch prediction,
+    as the cpu assumes that backward branches are always taken; so
+    instead copy the trick from the Linux kernel, introduce a forward
+    branch and back again.
+
+    I have, however, had a hard time measuring the difference between
+    the two versions in microbenchmarks -- I am leaving it in nevertheless
+    as it apparently does not hurt either.
+*/
+
+struct gcc_alpha_operations_base
+{
+    static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false;
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
+
+    static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT
+    {
+        if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u)
+            __asm__ __volatile__ ("mb" ::: "memory");
+    }
+
+    static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT
+    {
+        if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u)
+            __asm__ __volatile__ ("mb" ::: "memory");
+    }
+
+    static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
+    {
+        if (order == memory_order_seq_cst)
+            __asm__ __volatile__ ("mb" ::: "memory");
+    }
+};
+
+
+template< bool Signed >
+struct operations< 4u, Signed > :
+    public gcc_alpha_operations_base
+{
+    typedef typename storage_traits< 4u >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 4u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        storage = v;
+        fence_after_store(order);
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v = storage;
+        fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, tmp;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "mov %3, %1\n"
+            "ldl_l %0, %2\n"
+            "stl_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (tmp)        // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        fence_before(success_order);
+        int success;
+        storage_type current;
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldl_l %2, %4\n"                // current = *(&storage)
+            "cmpeq %2, %0, %3\n"            // success = current == expected
+            "mov %2, %0\n"                  // expected = current
+            "beq %3, 2f\n"                  // if (success == 0) goto end
+            "stl_c %1, %4\n"                // storage = desired; desired = store succeeded
+            "mov %1, %3\n"                  // success = desired
+            "2:\n"
+            : "+&r" (expected),  // %0
+              "+&r" (desired),   // %1
+              "=&r" (current),   // %2
+              "=&r" (success)    // %3
+            : "m" (storage)      // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        int success;
+        storage_type current, tmp;
+        fence_before(success_order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "mov %5, %1\n"                  // tmp = desired
+            "ldl_l %2, %4\n"                // current = *(&storage)
+            "cmpeq %2, %0, %3\n"            // success = current == expected
+            "mov %2, %0\n"                  // expected = current
+            "beq %3, 2f\n"                  // if (success == 0) goto end
+            "stl_c %1, %4\n"                // storage = tmp; tmp = store succeeded
+            "beq %1, 3f\n"                  // if (tmp == 0) goto retry
+            "mov %1, %3\n"                  // success = tmp
+            "2:\n"
+
+            ".subsection 2\n"
+            "3: br 1b\n"
+            ".previous\n"
+
+            : "+&r" (expected),  // %0
+              "=&r" (tmp),       // %1
+              "=&r" (current),   // %2
+              "=&r" (success)    // %3
+            : "m" (storage),     // %4
+              "r" (desired)      // %5
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldl_l %0, %2\n"
+            "addl %0, %3, %1\n"
+            "stl_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldl_l %0, %2\n"
+            "subl %0, %3, %1\n"
+            "stl_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldl_l %0, %2\n"
+            "and %0, %3, %1\n"
+            "stl_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldl_l %0, %2\n"
+            "bis %0, %3, %1\n"
+            "stl_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldl_l %0, %2\n"
+            "xor %0, %3, %1\n"
+            "stl_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!exchange(storage, (storage_type)1, order);
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        store(storage, 0, order);
+    }
+};
+
+
+template< >
+struct operations< 1u, false > :
+    public operations< 4u, false >
+{
+    typedef operations< 4u, false > base_type;
+    typedef base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldl_l %0, %2\n"
+            "addl %0, %3, %1\n"
+            "zapnot %1, #1, %1\n"
+            "stl_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldl_l %0, %2\n"
+            "subl %0, %3, %1\n"
+            "zapnot %1, #1, %1\n"
+            "stl_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+};
+
+template< >
+struct operations< 1u, true > :
+    public operations< 4u, true >
+{
+    typedef operations< 4u, true > base_type;
+    typedef base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldl_l %0, %2\n"
+            "addl %0, %3, %1\n"
+            "sextb %1, %1\n"
+            "stl_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldl_l %0, %2\n"
+            "subl %0, %3, %1\n"
+            "sextb %1, %1\n"
+            "stl_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+};
+
+
+template< >
+struct operations< 2u, false > :
+    public operations< 4u, false >
+{
+    typedef operations< 4u, false > base_type;
+    typedef base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldl_l %0, %2\n"
+            "addl %0, %3, %1\n"
+            "zapnot %1, #3, %1\n"
+            "stl_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldl_l %0, %2\n"
+            "subl %0, %3, %1\n"
+            "zapnot %1, #3, %1\n"
+            "stl_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+};
+
+template< >
+struct operations< 2u, true > :
+    public operations< 4u, true >
+{
+    typedef operations< 4u, true > base_type;
+    typedef base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldl_l %0, %2\n"
+            "addl %0, %3, %1\n"
+            "sextw %1, %1\n"
+            "stl_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldl_l %0, %2\n"
+            "subl %0, %3, %1\n"
+            "sextw %1, %1\n"
+            "stl_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+};
+
+
+template< bool Signed >
+struct operations< 8u, Signed > :
+    public gcc_alpha_operations_base
+{
+    typedef typename storage_traits< 8u >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 8u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        storage = v;
+        fence_after_store(order);
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v = storage;
+        fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, tmp;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "mov %3, %1\n"
+            "ldq_l %0, %2\n"
+            "stq_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (tmp)        // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        fence_before(success_order);
+        int success;
+        storage_type current;
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldq_l %2, %4\n"                // current = *(&storage)
+            "cmpeq %2, %0, %3\n"            // success = current == expected
+            "mov %2, %0\n"                  // expected = current
+            "beq %3, 2f\n"                  // if (success == 0) goto end
+            "stq_c %1, %4\n"                // storage = desired; desired = store succeeded
+            "mov %1, %3\n"                  // success = desired
+            "2:\n"
+            : "+&r" (expected),  // %0
+              "+&r" (desired),   // %1
+              "=&r" (current),   // %2
+              "=&r" (success)    // %3
+            : "m" (storage)      // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        int success;
+        storage_type current, tmp;
+        fence_before(success_order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "mov %5, %1\n"                  // tmp = desired
+            "ldq_l %2, %4\n"                // current = *(&storage)
+            "cmpeq %2, %0, %3\n"            // success = current == expected
+            "mov %2, %0\n"                  // expected = current
+            "beq %3, 2f\n"                  // if (success == 0) goto end
+            "stq_c %1, %4\n"                // storage = tmp; tmp = store succeeded
+            "beq %1, 3f\n"                  // if (tmp == 0) goto retry
+            "mov %1, %3\n"                  // success = tmp
+            "2:\n"
+
+            ".subsection 2\n"
+            "3: br 1b\n"
+            ".previous\n"
+
+            : "+&r" (expected),  // %0
+              "=&r" (tmp),       // %1
+              "=&r" (current),   // %2
+              "=&r" (success)    // %3
+            : "m" (storage),     // %4
+              "r" (desired)      // %5
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldq_l %0, %2\n"
+            "addq %0, %3, %1\n"
+            "stq_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldq_l %0, %2\n"
+            "subq %0, %3, %1\n"
+            "stq_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldq_l %0, %2\n"
+            "and %0, %3, %1\n"
+            "stq_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldq_l %0, %2\n"
+            "bis %0, %3, %1\n"
+            "stq_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, modified;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n"
+            "ldq_l %0, %2\n"
+            "xor %0, %3, %1\n"
+            "stq_c %1, %2\n"
+            "beq %1, 2f\n"
+
+            ".subsection 2\n"
+            "2: br 1b\n"
+            ".previous\n"
+
+            : "=&r" (original),  // %0
+              "=&r" (modified)   // %1
+            : "m" (storage),     // %2
+              "r" (v)            // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!exchange(storage, (storage_type)1, order);
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        store(storage, (storage_type)0, order);
+    }
+};
+
+
+BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
+{
+    if (order != memory_order_relaxed)
+        __asm__ __volatile__ ("mb" ::: "memory");
+}
+
+BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
+{
+    if (order != memory_order_relaxed)
+        __asm__ __volatile__ ("" ::: "memory");
+}
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_ALPHA_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_gcc_arm.hpp b/ThirdParty/boost/atomic/detail/ops_gcc_arm.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3eb2d6a95fd1867e7372ef3e806ce186e43e05eb
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_gcc_arm.hpp
@@ -0,0 +1,1397 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_gcc_arm.hpp
+ *
+ * This header contains implementation of the \c operations template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_ARM_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_GCC_ARM_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/cstdint.hpp>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/integral_conversions.hpp>
+#include <boost/atomic/detail/operations_fwd.hpp>
+#include <boost/atomic/detail/ops_gcc_arm_common.hpp>
+#include <boost/atomic/capabilities.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+// From the ARM Architecture Reference Manual for architecture v6:
+//
+// LDREX{<cond>} <Rd>, [<Rn>]
+// <Rd> Specifies the destination register for the memory word addressed by <Rd>
+// <Rn> Specifies the register containing the address.
+//
+// STREX{<cond>} <Rd>, <Rm>, [<Rn>]
+// <Rd> Specifies the destination register for the returned status value.
+//      0  if the operation updates memory
+//      1  if the operation fails to update memory
+// <Rm> Specifies the register containing the word to be stored to memory.
+// <Rn> Specifies the register containing the address.
+// Rd must not be the same register as Rm or Rn.
+//
+// ARM v7 is like ARM v6 plus:
+// There are half-word and byte versions of the LDREX and STREX instructions,
+// LDREXH, LDREXB, STREXH and STREXB.
+// There are also double-word versions, LDREXD and STREXD.
+// (Actually it looks like these are available from version 6k onwards.)
+// FIXME these are not yet used; should be mostly a matter of copy-and-paste.
+// I think you can supply an immediate offset to the address.
+
+template< bool Signed >
+struct operations< 4u, Signed > :
+    public gcc_arm_operations_base
+{
+    typedef typename storage_traits< 4u >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 4u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        storage = v;
+        fence_after_store(order);
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v = storage;
+        fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original;
+        fence_before(order);
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex %[original], %[storage]\n"          // load the original value
+            "strex %[tmp], %[value], %[storage]\n"     // store the replacement, tmp = store failed
+            "teq   %[tmp], #0\n"                       // check if store succeeded
+            "bne   1b\n"
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [tmp] "=&l" (tmp), [original] "=&r" (original), [storage] "+Q" (storage)
+            : [value] "r" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        fence_before(success_order);
+        uint32_t success;
+        uint32_t tmp;
+        storage_type original;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "mov     %[success], #0\n"                      // success = 0
+            "ldrex   %[original], %[storage]\n"             // original = *(&storage)
+            "cmp     %[original], %[expected]\n"            // flags = original==expected
+            "itt     eq\n"                                  // [hint that the following 2 instructions are conditional on flags.equal]
+            "strexeq %[success], %[desired], %[storage]\n"  // if (flags.equal) *(&storage) = desired, success = store failed
+            "eoreq   %[success], %[success], #1\n"          // if (flags.equal) success ^= 1 (i.e. make it 1 if store succeeded)
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [success] "=&r" (success),    // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [expected] "Ir" (expected),   // %4
+              [desired] "r" (desired)       // %5
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        expected = original;
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        fence_before(success_order);
+        uint32_t success;
+        uint32_t tmp;
+        storage_type original;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "mov     %[success], #0\n"                      // success = 0
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"             // original = *(&storage)
+            "cmp     %[original], %[expected]\n"            // flags = original==expected
+            "bne     2f\n"                                  // if (!flags.equal) goto end
+            "strex   %[success], %[desired], %[storage]\n"  // *(&storage) = desired, success = store failed
+            "eors    %[success], %[success], #1\n"          // success ^= 1 (i.e. make it 1 if store succeeded); flags.equal = success == 0
+            "beq     1b\n"                                  // if (flags.equal) goto retry
+            "2:\n"
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [success] "=&r" (success),    // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [expected] "Ir" (expected),   // %4
+              [desired] "r" (desired)       // %5
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        expected = original;
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "add     %[result], %[original], %[value]\n"  // result = original + value
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "sub     %[result], %[original], %[value]\n"  // result = original - value
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "and     %[result], %[original], %[value]\n"  // result = original & value
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "orr     %[result], %[original], %[value]\n"  // result = original | value
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "eor     %[result], %[original], %[value]\n"  // result = original ^ value
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!exchange(storage, (storage_type)1, order);
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        store(storage, (storage_type)0, order);
+    }
+};
+
+#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB)
+
+template< bool Signed >
+struct operations< 1u, Signed > :
+    public gcc_arm_operations_base
+{
+    typedef typename storage_traits< 1u >::type storage_type;
+    typedef typename storage_traits< 4u >::type extended_storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 1u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 1u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        storage = v;
+        fence_after_store(order);
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v = storage;
+        fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        extended_storage_type original;
+        fence_before(order);
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexb %[original], %[storage]\n"          // load the original value and zero-extend to 32 bits
+            "strexb %[tmp], %[value], %[storage]\n"     // store the replacement, tmp = store failed
+            "teq    %[tmp], #0\n"                       // check if store succeeded
+            "bne    1b\n"
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [tmp] "=&l" (tmp), [original] "=&r" (original), [storage] "+Q" (storage)
+            : [value] "r" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return static_cast< storage_type >(original);
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        fence_before(success_order);
+        uint32_t success;
+        uint32_t tmp;
+        extended_storage_type original;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "mov      %[success], #0\n"                      // success = 0
+            "ldrexb   %[original], %[storage]\n"             // original = zero_extend(*(&storage))
+            "cmp      %[original], %[expected]\n"            // flags = original==expected
+            "itt      eq\n"                                  // [hint that the following 2 instructions are conditional on flags.equal]
+            "strexbeq %[success], %[desired], %[storage]\n"  // if (flags.equal) *(&storage) = desired, success = store failed
+            "eoreq    %[success], %[success], #1\n"          // if (flags.equal) success ^= 1 (i.e. make it 1 if store succeeded)
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [success] "=&r" (success),    // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [expected] "Ir" (atomics::detail::zero_extend< extended_storage_type >(expected)),   // %4
+              [desired] "r" (desired)       // %5
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        expected = static_cast< storage_type >(original);
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        fence_before(success_order);
+        uint32_t success;
+        uint32_t tmp;
+        extended_storage_type original;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "mov      %[success], #0\n"                      // success = 0
+            "1:\n"
+            "ldrexb   %[original], %[storage]\n"             // original = zero_extend(*(&storage))
+            "cmp      %[original], %[expected]\n"            // flags = original==expected
+            "bne      2f\n"                                  // if (!flags.equal) goto end
+            "strexb   %[success], %[desired], %[storage]\n"  // *(&storage) = desired, success = store failed
+            "eors     %[success], %[success], #1\n"          // success ^= 1 (i.e. make it 1 if store succeeded); flags.equal = success == 0
+            "beq      1b\n"                                  // if (flags.equal) goto retry
+            "2:\n"
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [success] "=&r" (success),    // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [expected] "Ir" (atomics::detail::zero_extend< extended_storage_type >(expected)),   // %4
+              [desired] "r" (desired)       // %5
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        expected = static_cast< storage_type >(original);
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexb   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "add      %[result], %[original], %[value]\n"  // result = original + value
+            "strexb   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return static_cast< storage_type >(original);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexb   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "sub      %[result], %[original], %[value]\n"  // result = original - value
+            "strexb   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return static_cast< storage_type >(original);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexb   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "and      %[result], %[original], %[value]\n"  // result = original & value
+            "strexb   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return static_cast< storage_type >(original);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexb   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "orr      %[result], %[original], %[value]\n"  // result = original | value
+            "strexb   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return static_cast< storage_type >(original);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexb   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "eor      %[result], %[original], %[value]\n"  // result = original ^ value
+            "strexb   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return static_cast< storage_type >(original);
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!exchange(storage, (storage_type)1, order);
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        store(storage, (storage_type)0, order);
+    }
+};
+
+#else // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB)
+
+template< >
+struct operations< 1u, false > :
+    public operations< 4u, false >
+{
+    typedef operations< 4u, false > base_type;
+    typedef base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "add     %[result], %[original], %[value]\n"  // result = original + value
+            "uxtb    %[result], %[result]\n"              // zero extend result from 8 to 32 bits
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "sub     %[result], %[original], %[value]\n"  // result = original - value
+            "uxtb    %[result], %[result]\n"              // zero extend result from 8 to 32 bits
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+};
+
+template< >
+struct operations< 1u, true > :
+    public operations< 4u, true >
+{
+    typedef operations< 4u, true > base_type;
+    typedef base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "add     %[result], %[original], %[value]\n"  // result = original + value
+            "sxtb    %[result], %[result]\n"              // sign extend result from 8 to 32 bits
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "sub     %[result], %[original], %[value]\n"  // result = original - value
+            "sxtb    %[result], %[result]\n"              // sign extend result from 8 to 32 bits
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+};
+
+#endif // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB)
+
+#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH)
+
+template< bool Signed >
+struct operations< 2u, Signed > :
+    public gcc_arm_operations_base
+{
+    typedef typename storage_traits< 2u >::type storage_type;
+    typedef typename storage_traits< 4u >::type extended_storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 2u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 2u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        storage = v;
+        fence_after_store(order);
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v = storage;
+        fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        extended_storage_type original;
+        fence_before(order);
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexh %[original], %[storage]\n"          // load the original value and zero-extend to 32 bits
+            "strexh %[tmp], %[value], %[storage]\n"     // store the replacement, tmp = store failed
+            "teq    %[tmp], #0\n"                       // check if store succeeded
+            "bne    1b\n"
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [tmp] "=&l" (tmp), [original] "=&r" (original), [storage] "+Q" (storage)
+            : [value] "r" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return static_cast< storage_type >(original);
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        fence_before(success_order);
+        uint32_t success;
+        uint32_t tmp;
+        extended_storage_type original;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "mov      %[success], #0\n"                      // success = 0
+            "ldrexh   %[original], %[storage]\n"             // original = zero_extend(*(&storage))
+            "cmp      %[original], %[expected]\n"            // flags = original==expected
+            "itt      eq\n"                                  // [hint that the following 2 instructions are conditional on flags.equal]
+            "strexheq %[success], %[desired], %[storage]\n"  // if (flags.equal) *(&storage) = desired, success = store failed
+            "eoreq    %[success], %[success], #1\n"          // if (flags.equal) success ^= 1 (i.e. make it 1 if store succeeded)
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [success] "=&r" (success),    // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [expected] "Ir" (atomics::detail::zero_extend< extended_storage_type >(expected)),   // %4
+              [desired] "r" (desired)       // %5
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        expected = static_cast< storage_type >(original);
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        fence_before(success_order);
+        uint32_t success;
+        uint32_t tmp;
+        extended_storage_type original;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "mov      %[success], #0\n"                      // success = 0
+            "1:\n"
+            "ldrexh   %[original], %[storage]\n"             // original = zero_extend(*(&storage))
+            "cmp      %[original], %[expected]\n"            // flags = original==expected
+            "bne      2f\n"                                  // if (!flags.equal) goto end
+            "strexh   %[success], %[desired], %[storage]\n"  // *(&storage) = desired, success = store failed
+            "eors     %[success], %[success], #1\n"          // success ^= 1 (i.e. make it 1 if store succeeded); flags.equal = success == 0
+            "beq      1b\n"                                  // if (flags.equal) goto retry
+            "2:\n"
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [success] "=&r" (success),    // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [expected] "Ir" (atomics::detail::zero_extend< extended_storage_type >(expected)),   // %4
+              [desired] "r" (desired)       // %5
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        expected = static_cast< storage_type >(original);
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexh   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "add      %[result], %[original], %[value]\n"  // result = original + value
+            "strexh   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return static_cast< storage_type >(original);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexh   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "sub      %[result], %[original], %[value]\n"  // result = original - value
+            "strexh   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return static_cast< storage_type >(original);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexh   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "and      %[result], %[original], %[value]\n"  // result = original & value
+            "strexh   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return static_cast< storage_type >(original);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexh   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "orr      %[result], %[original], %[value]\n"  // result = original | value
+            "strexh   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return static_cast< storage_type >(original);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        extended_storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrexh   %[original], %[storage]\n"           // original = zero_extend(*(&storage))
+            "eor      %[result], %[original], %[value]\n"  // result = original ^ value
+            "strexh   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq      %[tmp], #0\n"                        // flags = tmp==0
+            "bne      1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return static_cast< storage_type >(original);
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!exchange(storage, (storage_type)1, order);
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        store(storage, (storage_type)0, order);
+    }
+};
+
+#else // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH)
+
+template< >
+struct operations< 2u, false > :
+    public operations< 4u, false >
+{
+    typedef operations< 4u, false > base_type;
+    typedef base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "add     %[result], %[original], %[value]\n"  // result = original + value
+            "uxth    %[result], %[result]\n"              // zero extend result from 16 to 32 bits
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "sub     %[result], %[original], %[value]\n"  // result = original - value
+            "uxth    %[result], %[result]\n"              // zero extend result from 16 to 32 bits
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+};
+
+template< >
+struct operations< 2u, true > :
+    public operations< 4u, true >
+{
+    typedef operations< 4u, true > base_type;
+    typedef base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "add     %[result], %[original], %[value]\n"  // result = original + value
+            "sxth    %[result], %[result]\n"              // sign extend result from 16 to 32 bits
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        uint32_t tmp;
+        storage_type original, result;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%[tmp])
+            "1:\n"
+            "ldrex   %[original], %[storage]\n"           // original = *(&storage)
+            "sub     %[result], %[original], %[value]\n"  // result = original - value
+            "sxth    %[result], %[result]\n"              // sign extend result from 16 to 32 bits
+            "strex   %[tmp], %[result], %[storage]\n"     // *(&storage) = result, tmp = store failed
+            "teq     %[tmp], #0\n"                        // flags = tmp==0
+            "bne     1b\n"                                // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%[tmp])
+            : [original] "=&r" (original),  // %0
+              [result] "=&r" (result),      // %1
+              [tmp] "=&l" (tmp),            // %2
+              [storage] "+Q" (storage)      // %3
+            : [value] "Ir" (v)              // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+};
+
+#endif // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH)
+
+#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD)
+
+// Unlike 32-bit operations, for 64-bit loads and stores we must use ldrexd/strexd.
+// Any other instructions result in a non-atomic sequence of 32-bit accesses.
+// See "ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition",
+// Section A3.5.3 "Atomicity in the ARM architecture".
+
+// In the asm blocks below we have to use 32-bit register pairs to compose 64-bit values.
+// In order to pass the 64-bit operands to/from asm blocks, we use undocumented gcc feature:
+// the lower half (Rt) of the operand is accessible normally, via the numbered placeholder (e.g. %0),
+// and the upper half (Rt2) - via the same placeholder with an 'H' after the '%' sign (e.g. %H0).
+// See: http://hardwarebug.org/2010/07/06/arm-inline-asm-secrets/
+
+template< bool Signed >
+struct operations< 8u, Signed > :
+    public gcc_arm_operations_base
+{
+    typedef typename storage_traits< 8u >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 8u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        exchange(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original;
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "ldrexd %1, %H1, [%2]\n"
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original)   // %1
+            : "r" (&storage)     // %2
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original;
+        fence_before(order);
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "1:\n"
+            "ldrexd %1, %H1, [%3]\n"        // load the original value
+            "strexd %0, %2, %H2, [%3]\n"    // store the replacement, tmp = store failed
+            "teq    %0, #0\n"               // check if store succeeded
+            "bne    1b\n"
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original)   // %1
+            : "r" (v),           // %2
+              "r" (&storage)     // %3
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        fence_before(success_order);
+        uint32_t tmp;
+        storage_type original, old_val = expected;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "ldrexd   %1, %H1, [%3]\n"               // original = *(&storage)
+            "cmp      %1, %2\n"                      // flags = original.lo==old_val.lo
+            "ittt     eq\n"                          // [hint that the following 3 instructions are conditional on flags.equal]
+            "cmpeq    %H1, %H2\n"                    // if (flags.equal) flags = original.hi==old_val.hi
+            "strexdeq %0, %4, %H4, [%3]\n"           // if (flags.equal) *(&storage) = desired, tmp = store failed
+            "teqeq    %0, #0\n"                      // if (flags.equal) flags = tmp==0
+            "ite      eq\n"                          // [hint that the following 2 instructions are conditional on flags.equal]
+            "moveq    %2, #1\n"                      // if (flags.equal) old_val.lo = 1
+            "movne    %2, #0\n"                      // if (!flags.equal) old_val.lo = 0
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original),  // %1
+              "+r" (old_val)     // %2
+            : "r" (&storage),    // %3
+              "r" (desired)      // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        const uint32_t success = (uint32_t)old_val;
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        expected = original;
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        fence_before(success_order);
+        uint32_t tmp;
+        storage_type original, old_val = expected;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "1:\n"
+            "ldrexd  %1, %H1, [%3]\n"               // original = *(&storage)
+            "cmp     %1, %2\n"                      // flags = original.lo==old_val.lo
+            "it      eq\n"                          // [hint that the following instruction is conditional on flags.equal]
+            "cmpeq   %H1, %H2\n"                    // if (flags.equal) flags = original.hi==old_val.hi
+            "bne     2f\n"                          // if (!flags.equal) goto end
+            "strexd  %0, %4, %H4, [%3]\n"           // *(&storage) = desired, tmp = store failed
+            "teq     %0, #0\n"                      // flags.equal = tmp == 0
+            "bne     1b\n"                          // if (flags.equal) goto retry
+            "2:\n"
+            "ite      eq\n"                         // [hint that the following 2 instructions are conditional on flags.equal]
+            "moveq    %2, #1\n"                     // if (flags.equal) old_val.lo = 1
+            "movne    %2, #0\n"                     // if (!flags.equal) old_val.lo = 0
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original),  // %1
+              "+r" (old_val)     // %2
+            : "r" (&storage),    // %3
+              "r" (desired)      // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        const uint32_t success = (uint32_t)old_val;
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        expected = original;
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        storage_type original, result;
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "1:\n"
+            "ldrexd  %1, %H1, [%3]\n"               // original = *(&storage)
+            "adds    %2, %1, %4\n"                  // result = original + value
+            "adc     %H2, %H1, %H4\n"
+            "strexd  %0, %2, %H2, [%3]\n"           // *(&storage) = result, tmp = store failed
+            "teq     %0, #0\n"                      // flags = tmp==0
+            "bne     1b\n"                          // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original),  // %1
+              "=&r" (result)     // %2
+            : "r" (&storage),    // %3
+              "r" (v)            // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        storage_type original, result;
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "1:\n"
+            "ldrexd  %1, %H1, [%3]\n"               // original = *(&storage)
+            "subs    %2, %1, %4\n"                  // result = original - value
+            "sbc     %H2, %H1, %H4\n"
+            "strexd  %0, %2, %H2, [%3]\n"           // *(&storage) = result, tmp = store failed
+            "teq     %0, #0\n"                      // flags = tmp==0
+            "bne     1b\n"                          // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original),  // %1
+              "=&r" (result)     // %2
+            : "r" (&storage),    // %3
+              "r" (v)            // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        storage_type original, result;
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "1:\n"
+            "ldrexd  %1, %H1, [%3]\n"               // original = *(&storage)
+            "and     %2, %1, %4\n"                  // result = original & value
+            "and     %H2, %H1, %H4\n"
+            "strexd  %0, %2, %H2, [%3]\n"           // *(&storage) = result, tmp = store failed
+            "teq     %0, #0\n"                      // flags = tmp==0
+            "bne     1b\n"                          // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original),  // %1
+              "=&r" (result)     // %2
+            : "r" (&storage),    // %3
+              "r" (v)            // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        storage_type original, result;
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "1:\n"
+            "ldrexd  %1, %H1, [%3]\n"               // original = *(&storage)
+            "orr     %2, %1, %4\n"                  // result = original | value
+            "orr     %H2, %H1, %H4\n"
+            "strexd  %0, %2, %H2, [%3]\n"           // *(&storage) = result, tmp = store failed
+            "teq     %0, #0\n"                      // flags = tmp==0
+            "bne     1b\n"                          // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original),  // %1
+              "=&r" (result)     // %2
+            : "r" (&storage),    // %3
+              "r" (v)            // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        storage_type original, result;
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "1:\n"
+            "ldrexd  %1, %H1, [%3]\n"               // original = *(&storage)
+            "eor     %2, %1, %4\n"                  // result = original ^ value
+            "eor     %H2, %H1, %H4\n"
+            "strexd  %0, %2, %H2, [%3]\n"           // *(&storage) = result, tmp = store failed
+            "teq     %0, #0\n"                      // flags = tmp==0
+            "bne     1b\n"                          // if (!flags.equal) goto retry
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(tmp), // %0
+              "=&r" (original),  // %1
+              "=&r" (result)     // %2
+            : "r" (&storage),    // %3
+              "r" (v)            // %4
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!exchange(storage, (storage_type)1, order);
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        store(storage, (storage_type)0, order);
+    }
+};
+
+#endif // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXD_STREXD)
+
+
+BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
+{
+    if (order != memory_order_relaxed)
+        gcc_arm_operations_base::hardware_full_fence();
+}
+
+BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
+{
+    if (order != memory_order_relaxed)
+        __asm__ __volatile__ ("" ::: "memory");
+}
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_ARM_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_gcc_arm_common.hpp b/ThirdParty/boost/atomic/detail/ops_gcc_arm_common.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..73c04ffe1577dbb3ad25ac27ea62676922643c88
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_gcc_arm_common.hpp
@@ -0,0 +1,134 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_gcc_arm_common.hpp
+ *
+ * This header contains basic utilities for gcc ARM backend.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_ARM_COMMON_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_GCC_ARM_COMMON_HPP_INCLUDED_
+
+#include <boost/cstdint.hpp>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+// A memory barrier is effected using a "co-processor 15" instruction,
+// though a separate assembler mnemonic is available for it in v7.
+//
+// "Thumb 1" is a subset of the ARM instruction set that uses a 16-bit encoding.  It
+// doesn't include all instructions and in particular it doesn't include the co-processor
+// instruction used for the memory barrier or the load-locked/store-conditional
+// instructions.  So, if we're compiling in "Thumb 1" mode, we need to wrap all of our
+// asm blocks with code to temporarily change to ARM mode.
+//
+// You can only change between ARM and Thumb modes when branching using the bx instruction.
+// bx takes an address specified in a register.  The least significant bit of the address
+// indicates the mode, so 1 is added to indicate that the destination code is Thumb.
+// A temporary register is needed for the address and is passed as an argument to these
+// macros.  It must be one of the "low" registers accessible to Thumb code, specified
+// using the "l" attribute in the asm statement.
+//
+// Architecture v7 introduces "Thumb 2", which does include (almost?) all of the ARM
+// instruction set.  (Actually, there was an extension of v6 called v6T2 which supported
+// "Thumb 2" mode, but its architecture manual is no longer available, referring to v7.)
+// So in v7 we don't need to change to ARM mode; we can write "universal
+// assembler" which will assemble to Thumb 2 or ARM code as appropriate.  The only thing
+// we need to do to make this "universal" assembler mode work is to insert "IT" instructions
+// to annotate the conditional instructions.  These are ignored in other modes (e.g. v6),
+// so they can always be present.
+
+// A note about memory_order_consume. Technically, this architecture allows to avoid
+// unnecessary memory barrier after consume load since it supports data dependency ordering.
+// However, some compiler optimizations may break a seemingly valid code relying on data
+// dependency tracking by injecting bogus branches to aid out of order execution.
+// This may happen not only in Boost.Atomic code but also in user's code, which we have no
+// control of. See this thread: http://lists.boost.org/Archives/boost/2014/06/213890.php.
+// For this reason we promote memory_order_consume to memory_order_acquire.
+
+#if defined(__thumb__) && !defined(__thumb2__)
+#define BOOST_ATOMIC_DETAIL_ARM_ASM_START(TMPREG) "adr " #TMPREG ", 8f\n" "bx " #TMPREG "\n" ".arm\n" ".align 4\n" "8:\n"
+#define BOOST_ATOMIC_DETAIL_ARM_ASM_END(TMPREG)   "adr " #TMPREG ", 9f + 1\n" "bx " #TMPREG "\n" ".thumb\n" ".align 2\n" "9:\n"
+#define BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(var) "=&l" (var)
+#else
+// The tmpreg may be wasted in this case, which is non-optimal.
+#define BOOST_ATOMIC_DETAIL_ARM_ASM_START(TMPREG)
+#define BOOST_ATOMIC_DETAIL_ARM_ASM_END(TMPREG)
+#define BOOST_ATOMIC_DETAIL_ARM_ASM_TMPREG_CONSTRAINT(var) "=&r" (var)
+#endif
+
+struct gcc_arm_operations_base
+{
+    static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false;
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
+
+    static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT
+    {
+        if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u)
+            hardware_full_fence();
+    }
+
+    static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT
+    {
+        if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u)
+            hardware_full_fence();
+    }
+
+    static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
+    {
+        if (order == memory_order_seq_cst)
+            hardware_full_fence();
+    }
+
+    static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_DMB)
+        // Older binutils (supposedly, older than 2.21.1) didn't support symbolic or numeric arguments of the "dmb" instruction such as "ish" or "#11".
+        // As a workaround we have to inject encoded bytes of the instruction. There are two encodings for the instruction: ARM and Thumb. See ARM Architecture Reference Manual, A8.8.43.
+        // Since we cannot detect binutils version at compile time, we'll have to always use this hack.
+        __asm__ __volatile__
+        (
+#if defined(__thumb2__)
+            ".short 0xF3BF, 0x8F5B\n" // dmb ish
+#else
+            ".word 0xF57FF05B\n" // dmb ish
+#endif
+            :
+            :
+            : "memory"
+        );
+#else
+        uint32_t tmp;
+        __asm__ __volatile__
+        (
+            BOOST_ATOMIC_DETAIL_ARM_ASM_START(%0)
+            "mcr\tp15, 0, r0, c7, c10, 5\n"
+            BOOST_ATOMIC_DETAIL_ARM_ASM_END(%0)
+            : "=&l" (tmp)
+            :
+            : "memory"
+        );
+#endif
+    }
+};
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_ARM_COMMON_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_gcc_atomic.hpp b/ThirdParty/boost/atomic/detail/ops_gcc_atomic.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7360b882b6b7ea48ee5556aa6b6a6755cdd186db
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_gcc_atomic.hpp
@@ -0,0 +1,390 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_gcc_atomic.hpp
+ *
+ * This header contains implementation of the \c operations template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_ATOMIC_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_GCC_ATOMIC_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/operations_fwd.hpp>
+#include <boost/atomic/capabilities.hpp>
+#if (defined(__clang__) || (defined(BOOST_GCC) && (BOOST_GCC+0) >= 70000)) && (defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) || defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B))
+#include <boost/atomic/detail/ops_gcc_x86_dcas.hpp>
+#include <boost/atomic/detail/ops_cas_based.hpp>
+#endif
+
+#if __GCC_ATOMIC_LLONG_LOCK_FREE != BOOST_ATOMIC_LLONG_LOCK_FREE || __GCC_ATOMIC_LONG_LOCK_FREE != BOOST_ATOMIC_LONG_LOCK_FREE ||\
+    __GCC_ATOMIC_INT_LOCK_FREE != BOOST_ATOMIC_INT_LOCK_FREE || __GCC_ATOMIC_SHORT_LOCK_FREE != BOOST_ATOMIC_SHORT_LOCK_FREE ||\
+    __GCC_ATOMIC_CHAR_LOCK_FREE != BOOST_ATOMIC_CHAR_LOCK_FREE || __GCC_ATOMIC_BOOL_LOCK_FREE != BOOST_ATOMIC_BOOL_LOCK_FREE ||\
+    __GCC_ATOMIC_WCHAR_T_LOCK_FREE != BOOST_ATOMIC_WCHAR_T_LOCK_FREE
+// There are platforms where we need to use larger storage types
+#include <boost/atomic/detail/int_sizes.hpp>
+#include <boost/atomic/detail/ops_extending_cas_based.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(__INTEL_COMPILER)
+// This is used to suppress warning #32013 described below for Intel Compiler.
+// In debug builds the compiler does not inline any functions, so basically
+// every atomic function call results in this warning. I don't know any other
+// way to selectively disable just this one warning.
+#pragma system_header
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+/*!
+ * The function converts \c boost::memory_order values to the compiler-specific constants.
+ *
+ * NOTE: The intention is that the function is optimized away by the compiler, and the
+ *       compiler-specific constants are passed to the intrinsics. Unfortunately, constexpr doesn't
+ *       work in this case because the standard atomics interface require memory ordering
+ *       constants to be passed as function arguments, at which point they stop being constexpr.
+ *       However, it is crucial that the compiler sees constants and not runtime values,
+ *       because otherwise it just ignores the ordering value and always uses seq_cst.
+ *       This is the case with Intel C++ Compiler 14.0.3 (Composer XE 2013 SP1, update 3) and
+ *       gcc 4.8.2. Intel Compiler issues a warning in this case:
+ *
+ *       warning #32013: Invalid memory order specified. Defaulting to seq_cst memory order.
+ *
+ *       while gcc acts silently.
+ *
+ *       To mitigate the problem ALL functions, including the atomic<> members must be
+ *       declared with BOOST_FORCEINLINE. In this case the compilers are able to see that
+ *       all functions are called with constant orderings and call intrinstcts properly.
+ *
+ *       Unfortunately, this still doesn't work in debug mode as the compiler doesn't
+ *       propagate constants even when functions are marked with BOOST_FORCEINLINE. In this case
+ *       all atomic operaions will be executed with seq_cst semantics.
+ */
+BOOST_FORCEINLINE BOOST_CONSTEXPR int convert_memory_order_to_gcc(memory_order order) BOOST_NOEXCEPT
+{
+    return (order == memory_order_relaxed ? __ATOMIC_RELAXED : (order == memory_order_consume ? __ATOMIC_CONSUME :
+        (order == memory_order_acquire ? __ATOMIC_ACQUIRE : (order == memory_order_release ? __ATOMIC_RELEASE :
+        (order == memory_order_acq_rel ? __ATOMIC_ACQ_REL : __ATOMIC_SEQ_CST)))));
+}
+
+template< std::size_t Size, bool Signed >
+struct gcc_atomic_operations
+{
+    typedef typename storage_traits< Size >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = storage_traits< Size >::alignment;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+    static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false;
+
+    // Note: In the current implementation, gcc_atomic_operations are used only when the particularly sized __atomic
+    // intrinsics are always lock-free (i.e. the corresponding LOCK_FREE macro is 2). Therefore it is safe to
+    // always set is_always_lock_free to true here.
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        __atomic_store_n(&storage, v, atomics::detail::convert_memory_order_to_gcc(order));
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return __atomic_load_n(&storage, atomics::detail::convert_memory_order_to_gcc(order));
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return __atomic_fetch_add(&storage, v, atomics::detail::convert_memory_order_to_gcc(order));
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return __atomic_fetch_sub(&storage, v, atomics::detail::convert_memory_order_to_gcc(order));
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return __atomic_exchange_n(&storage, v, atomics::detail::convert_memory_order_to_gcc(order));
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        return __atomic_compare_exchange_n
+        (
+            &storage, &expected, desired, false,
+            atomics::detail::convert_memory_order_to_gcc(success_order),
+            atomics::detail::convert_memory_order_to_gcc(failure_order)
+        );
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        return __atomic_compare_exchange_n
+        (
+            &storage, &expected, desired, true,
+            atomics::detail::convert_memory_order_to_gcc(success_order),
+            atomics::detail::convert_memory_order_to_gcc(failure_order)
+        );
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return __atomic_fetch_and(&storage, v, atomics::detail::convert_memory_order_to_gcc(order));
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return __atomic_fetch_or(&storage, v, atomics::detail::convert_memory_order_to_gcc(order));
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return __atomic_fetch_xor(&storage, v, atomics::detail::convert_memory_order_to_gcc(order));
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return __atomic_test_and_set(&storage, atomics::detail::convert_memory_order_to_gcc(order));
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        __atomic_clear(const_cast< storage_type* >(&storage), atomics::detail::convert_memory_order_to_gcc(order));
+    }
+};
+
+#if BOOST_ATOMIC_INT128_LOCK_FREE > 0
+#if (defined(__clang__) || (defined(BOOST_GCC) && (BOOST_GCC+0) >= 70000)) && defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)
+
+// Workaround for clang bug: http://llvm.org/bugs/show_bug.cgi?id=19149
+// Clang 3.4 does not implement 128-bit __atomic* intrinsics even though it defines __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
+// A similar problem exists with gcc 7 as well, as it requires to link with libatomic to use 16-byte intrinsics:
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80878
+template< bool Signed >
+struct operations< 16u, Signed > :
+    public cas_based_operations< gcc_dcas_x86_64< Signed > >
+{
+};
+
+#else
+
+template< bool Signed >
+struct operations< 16u, Signed > :
+    public gcc_atomic_operations< 16u, Signed >
+{
+};
+
+#endif
+#endif
+
+
+#if BOOST_ATOMIC_INT64_LOCK_FREE > 0
+#if defined(__clang__) && defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B)
+
+// Workaround for clang bug http://llvm.org/bugs/show_bug.cgi?id=19355
+template< bool Signed >
+struct operations< 8u, Signed > :
+    public cas_based_operations< gcc_dcas_x86< Signed > >
+{
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+};
+
+#elif (BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 8 && __GCC_ATOMIC_LLONG_LOCK_FREE != BOOST_ATOMIC_LLONG_LOCK_FREE) ||\
+    (BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8 && __GCC_ATOMIC_LONG_LOCK_FREE != BOOST_ATOMIC_LONG_LOCK_FREE) ||\
+    (BOOST_ATOMIC_DETAIL_SIZEOF_INT == 8 && __GCC_ATOMIC_INT_LOCK_FREE != BOOST_ATOMIC_INT_LOCK_FREE) ||\
+    (BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 8 && __GCC_ATOMIC_SHORT_LOCK_FREE != BOOST_ATOMIC_SHORT_LOCK_FREE) ||\
+    (BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 8 && __GCC_ATOMIC_WCHAR_T_LOCK_FREE != BOOST_ATOMIC_WCHAR_T_LOCK_FREE)
+
+#define BOOST_ATOMIC_DETAIL_INT64_EXTENDED
+
+template< bool Signed >
+struct operations< 8u, Signed > :
+    public extending_cas_based_operations< gcc_atomic_operations< 16u, Signed >, 8u, Signed >
+{
+};
+
+#else
+
+template< bool Signed >
+struct operations< 8u, Signed > :
+    public gcc_atomic_operations< 8u, Signed >
+{
+};
+
+#endif
+#endif
+
+#if BOOST_ATOMIC_INT32_LOCK_FREE > 0
+#if (BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 4 && __GCC_ATOMIC_LLONG_LOCK_FREE != BOOST_ATOMIC_LLONG_LOCK_FREE) ||\
+    (BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 4 && __GCC_ATOMIC_LONG_LOCK_FREE != BOOST_ATOMIC_LONG_LOCK_FREE) ||\
+    (BOOST_ATOMIC_DETAIL_SIZEOF_INT == 4 && __GCC_ATOMIC_INT_LOCK_FREE != BOOST_ATOMIC_INT_LOCK_FREE) ||\
+    (BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 4 && __GCC_ATOMIC_SHORT_LOCK_FREE != BOOST_ATOMIC_SHORT_LOCK_FREE) ||\
+    (BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 4 && __GCC_ATOMIC_WCHAR_T_LOCK_FREE != BOOST_ATOMIC_WCHAR_T_LOCK_FREE)
+
+#define BOOST_ATOMIC_DETAIL_INT32_EXTENDED
+
+#if !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED)
+
+template< bool Signed >
+struct operations< 4u, Signed > :
+    public extending_cas_based_operations< gcc_atomic_operations< 8u, Signed >, 4u, Signed >
+{
+};
+
+#else // !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED)
+
+template< bool Signed >
+struct operations< 4u, Signed > :
+    public extending_cas_based_operations< gcc_atomic_operations< 16u, Signed >, 4u, Signed >
+{
+};
+
+#endif // !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED)
+
+#else
+
+template< bool Signed >
+struct operations< 4u, Signed > :
+    public gcc_atomic_operations< 4u, Signed >
+{
+};
+
+#endif
+#endif
+
+#if BOOST_ATOMIC_INT16_LOCK_FREE > 0
+#if (BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 2 && __GCC_ATOMIC_LLONG_LOCK_FREE != BOOST_ATOMIC_LLONG_LOCK_FREE) ||\
+    (BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 2 && __GCC_ATOMIC_LONG_LOCK_FREE != BOOST_ATOMIC_LONG_LOCK_FREE) ||\
+    (BOOST_ATOMIC_DETAIL_SIZEOF_INT == 2 && __GCC_ATOMIC_INT_LOCK_FREE != BOOST_ATOMIC_INT_LOCK_FREE) ||\
+    (BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 2 && __GCC_ATOMIC_SHORT_LOCK_FREE != BOOST_ATOMIC_SHORT_LOCK_FREE) ||\
+    (BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 2 && __GCC_ATOMIC_WCHAR_T_LOCK_FREE != BOOST_ATOMIC_WCHAR_T_LOCK_FREE)
+
+#define BOOST_ATOMIC_DETAIL_INT16_EXTENDED
+
+#if !defined(BOOST_ATOMIC_DETAIL_INT32_EXTENDED)
+
+template< bool Signed >
+struct operations< 2u, Signed > :
+    public extending_cas_based_operations< gcc_atomic_operations< 4u, Signed >, 2u, Signed >
+{
+};
+
+#elif !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED)
+
+template< bool Signed >
+struct operations< 2u, Signed > :
+    public extending_cas_based_operations< gcc_atomic_operations< 8u, Signed >, 2u, Signed >
+{
+};
+
+#else
+
+template< bool Signed >
+struct operations< 2u, Signed > :
+    public extending_cas_based_operations< gcc_atomic_operations< 16u, Signed >, 2u, Signed >
+{
+};
+
+#endif
+
+#else
+
+template< bool Signed >
+struct operations< 2u, Signed > :
+    public gcc_atomic_operations< 2u, Signed >
+{
+};
+
+#endif
+#endif
+
+#if BOOST_ATOMIC_INT8_LOCK_FREE > 0
+#if (BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 1 && __GCC_ATOMIC_LLONG_LOCK_FREE != BOOST_ATOMIC_LLONG_LOCK_FREE) ||\
+    (BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 1 && __GCC_ATOMIC_LONG_LOCK_FREE != BOOST_ATOMIC_LONG_LOCK_FREE) ||\
+    (BOOST_ATOMIC_DETAIL_SIZEOF_INT == 1 && __GCC_ATOMIC_INT_LOCK_FREE != BOOST_ATOMIC_INT_LOCK_FREE) ||\
+    (BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 1 && __GCC_ATOMIC_SHORT_LOCK_FREE != BOOST_ATOMIC_SHORT_LOCK_FREE) ||\
+    (BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 1 && __GCC_ATOMIC_WCHAR_T_LOCK_FREE != BOOST_ATOMIC_WCHAR_T_LOCK_FREE) ||\
+    (__GCC_ATOMIC_CHAR_LOCK_FREE != BOOST_ATOMIC_CHAR_LOCK_FREE) ||\
+    (__GCC_ATOMIC_BOOL_LOCK_FREE != BOOST_ATOMIC_BOOL_LOCK_FREE)
+
+#if !defined(BOOST_ATOMIC_DETAIL_INT16_EXTENDED)
+
+template< bool Signed >
+struct operations< 1u, Signed > :
+    public extending_cas_based_operations< gcc_atomic_operations< 2u, Signed >, 1u, Signed >
+{
+};
+
+#elif !defined(BOOST_ATOMIC_DETAIL_INT32_EXTENDED)
+
+template< bool Signed >
+struct operations< 1u, Signed > :
+    public extending_cas_based_operations< gcc_atomic_operations< 4u, Signed >, 1u, Signed >
+{
+};
+
+#elif !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED)
+
+template< bool Signed >
+struct operations< 1u, Signed > :
+    public extending_cas_based_operations< gcc_atomic_operations< 8u, Signed >, 1u, Signed >
+{
+};
+
+#else
+
+template< bool Signed >
+struct operations< 1u, Signed > :
+    public extending_cas_based_operations< gcc_atomic_operations< 16u, Signed >, 1u, Signed >
+{
+};
+
+#endif
+
+#else
+
+template< bool Signed >
+struct operations< 1u, Signed > :
+    public gcc_atomic_operations< 1u, Signed >
+{
+};
+
+#endif
+#endif
+
+#undef BOOST_ATOMIC_DETAIL_INT16_EXTENDED
+#undef BOOST_ATOMIC_DETAIL_INT32_EXTENDED
+#undef BOOST_ATOMIC_DETAIL_INT64_EXTENDED
+
+BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
+{
+    __atomic_thread_fence(atomics::detail::convert_memory_order_to_gcc(order));
+}
+
+BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
+{
+    __atomic_signal_fence(atomics::detail::convert_memory_order_to_gcc(order));
+}
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_ATOMIC_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_gcc_ppc.hpp b/ThirdParty/boost/atomic/detail/ops_gcc_ppc.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..82c03101d828b09b3b3b933822762b133183b99a
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_gcc_ppc.hpp
@@ -0,0 +1,1232 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_gcc_ppc.hpp
+ *
+ * This header contains implementation of the \c operations template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/operations_fwd.hpp>
+#include <boost/atomic/detail/ops_gcc_ppc_common.hpp>
+#include <boost/atomic/capabilities.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+// The implementation below uses information from this document:
+// http://www.rdrop.com/users/paulmck/scalability/paper/N2745r.2010.02.19a.html
+
+/*
+    Refer to: Motorola: "Programming Environments Manual for 32-Bit
+    Implementations of the PowerPC Architecture", Appendix E:
+    "Synchronization Programming Examples" for an explanation of what is
+    going on here (can be found on the web at various places by the
+    name "MPCFPE32B.pdf", Google is your friend...)
+
+    Most of the atomic operations map to instructions in a relatively
+    straight-forward fashion, but "load"s may at first glance appear
+    a bit strange as they map to:
+
+            lwz %rX, addr
+            cmpw %rX, %rX
+            bne- 1f
+        1:
+
+    That is, the CPU is forced to perform a branch that "formally" depends
+    on the value retrieved from memory. This scheme has an overhead of
+    about 1-2 clock cycles per load, but it allows to map "acquire" to
+    the "isync" instruction instead of "sync" uniformly and for all type
+    of atomic operations. Since "isync" has a cost of about 15 clock
+    cycles, while "sync" hast a cost of about 50 clock cycles, the small
+    penalty to atomic loads more than compensates for this.
+
+    Byte- and halfword-sized atomic values are implemented in two ways.
+    When 8 and 16-bit instructions are available (in Power8 and later),
+    they are used. Otherwise operations are realized by encoding the
+    value to be represented into a word, performing sign/zero extension
+    as appropriate. This means that after add/sub operations the value
+    needs fixing up to accurately preserve the wrap-around semantic of
+    the smaller type. (Nothing special needs to be done for the bit-wise
+    and the "exchange type" operators as the compiler already sees to
+    it that values carried in registers are extended appropriately and
+    everything falls into place naturally).
+
+    The register constraint "b"  instructs gcc to use any register
+    except r0; this is sometimes required because the encoding for
+    r0 is used to signify "constant zero" in a number of instructions,
+    making r0 unusable in this place. For simplicity this constraint
+    is used everywhere since I am to lazy to look this up on a
+    per-instruction basis, and ppc has enough registers for this not
+    to pose a problem.
+*/
+
+template< bool Signed >
+struct operations< 4u, Signed > :
+    public gcc_ppc_operations_base
+{
+    typedef typename storage_traits< 4u >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 4u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "stw %1, %0\n\t"
+            : "+m" (storage)
+            : "r" (v)
+        );
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v;
+        if (order == memory_order_seq_cst)
+            __asm__ __volatile__ ("sync" ::: "memory");
+        if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u)
+        {
+            __asm__ __volatile__
+            (
+                "lwz %0, %1\n\t"
+                "cmpw %0, %0\n\t"
+                "bne- 1f\n\t"
+                "1:\n\t"
+                "isync\n\t"
+                : "=&r" (v)
+                : "m" (storage)
+                : "cr0", "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lwz %0, %1\n\t"
+                : "=&r" (v)
+                : "m" (storage)
+            );
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y1\n\t"
+            "stwcx. %2,%y1\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "+Z" (storage)
+            : "b" (v)
+            : "cr0"
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        int success;
+        fence_before(success_order);
+        __asm__ __volatile__
+        (
+            "li %1, 0\n\t"
+            "lwarx %0,%y2\n\t"
+            "cmpw %0, %3\n\t"
+            "bne- 1f\n\t"
+            "stwcx. %4,%y2\n\t"
+            "bne- 1f\n\t"
+            "li %1, 1\n\t"
+            "1:\n\t"
+            : "=&b" (expected), "=&b" (success), "+Z" (storage)
+            : "b" (expected), "b" (desired)
+            : "cr0"
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        int success;
+        fence_before(success_order);
+        __asm__ __volatile__
+        (
+            "li %1, 0\n\t"
+            "0: lwarx %0,%y2\n\t"
+            "cmpw %0, %3\n\t"
+            "bne- 1f\n\t"
+            "stwcx. %4,%y2\n\t"
+            "bne- 0b\n\t"
+            "li %1, 1\n\t"
+            "1:\n\t"
+            : "=&b" (expected), "=&b" (success), "+Z" (storage)
+            : "b" (expected), "b" (desired)
+            : "cr0"
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "add %1,%0,%3\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "sub %1,%0,%3\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "and %1,%0,%3\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "or %1,%0,%3\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "xor %1,%0,%3\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!exchange(storage, (storage_type)1, order);
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        store(storage, (storage_type)0, order);
+    }
+};
+
+#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
+
+template< bool Signed >
+struct operations< 1u, Signed > :
+    public gcc_ppc_operations_base
+{
+    typedef typename storage_traits< 1u >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 1u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 1u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "stb %1, %0\n\t"
+            : "+m" (storage)
+            : "r" (v)
+        );
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v;
+        if (order == memory_order_seq_cst)
+            __asm__ __volatile__ ("sync" ::: "memory");
+        if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u)
+        {
+            __asm__ __volatile__
+            (
+                "lbz %0, %1\n\t"
+                "cmpw %0, %0\n\t"
+                "bne- 1f\n\t"
+                "1:\n\t"
+                "isync\n\t"
+                : "=&r" (v)
+                : "m" (storage)
+                : "cr0", "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lbz %0, %1\n\t"
+                : "=&r" (v)
+                : "m" (storage)
+            );
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lbarx %0,%y1\n\t"
+            "stbcx. %2,%y1\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "+Z" (storage)
+            : "b" (v)
+            : "cr0"
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        int success;
+        fence_before(success_order);
+        __asm__ __volatile__
+        (
+            "li %1, 0\n\t"
+            "lbarx %0,%y2\n\t"
+            "cmpw %0, %3\n\t"
+            "bne- 1f\n\t"
+            "stbcx. %4,%y2\n\t"
+            "bne- 1f\n\t"
+            "li %1, 1\n\t"
+            "1:\n\t"
+            : "=&b" (expected), "=&b" (success), "+Z" (storage)
+            : "b" (expected), "b" (desired)
+            : "cr0"
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        int success;
+        fence_before(success_order);
+        __asm__ __volatile__
+        (
+            "li %1, 0\n\t"
+            "0: lbarx %0,%y2\n\t"
+            "cmpw %0, %3\n\t"
+            "bne- 1f\n\t"
+            "stbcx. %4,%y2\n\t"
+            "bne- 0b\n\t"
+            "li %1, 1\n\t"
+            "1:\n\t"
+            : "=&b" (expected), "=&b" (success), "+Z" (storage)
+            : "b" (expected), "b" (desired)
+            : "cr0"
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lbarx %0,%y2\n\t"
+            "add %1,%0,%3\n\t"
+            "stbcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lbarx %0,%y2\n\t"
+            "sub %1,%0,%3\n\t"
+            "stbcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lbarx %0,%y2\n\t"
+            "and %1,%0,%3\n\t"
+            "stbcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lbarx %0,%y2\n\t"
+            "or %1,%0,%3\n\t"
+            "stbcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lbarx %0,%y2\n\t"
+            "xor %1,%0,%3\n\t"
+            "stbcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!exchange(storage, (storage_type)1, order);
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        store(storage, (storage_type)0, order);
+    }
+};
+
+#else // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
+
+template< >
+struct operations< 1u, false > :
+    public operations< 4u, false >
+{
+    typedef operations< 4u, false > base_type;
+    typedef base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "add %1,%0,%3\n\t"
+            "rlwinm %1, %1, 0, 0xff\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "sub %1,%0,%3\n\t"
+            "rlwinm %1, %1, 0, 0xff\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+};
+
+template< >
+struct operations< 1u, true > :
+    public operations< 4u, true >
+{
+    typedef operations< 4u, true > base_type;
+    typedef base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "add %1,%0,%3\n\t"
+            "extsb %1, %1\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "sub %1,%0,%3\n\t"
+            "extsb %1, %1\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+};
+
+#endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
+
+#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
+
+template< bool Signed >
+struct operations< 2u, Signed > :
+    public gcc_ppc_operations_base
+{
+    typedef typename storage_traits< 2u >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 2u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 2u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "sth %1, %0\n\t"
+            : "+m" (storage)
+            : "r" (v)
+        );
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v;
+        if (order == memory_order_seq_cst)
+            __asm__ __volatile__ ("sync" ::: "memory");
+        if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u)
+        {
+            __asm__ __volatile__
+            (
+                "lhz %0, %1\n\t"
+                "cmpw %0, %0\n\t"
+                "bne- 1f\n\t"
+                "1:\n\t"
+                "isync\n\t"
+                : "=&r" (v)
+                : "m" (storage)
+                : "cr0", "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "lhz %0, %1\n\t"
+                : "=&r" (v)
+                : "m" (storage)
+            );
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lharx %0,%y1\n\t"
+            "sthcx. %2,%y1\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "+Z" (storage)
+            : "b" (v)
+            : "cr0"
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        int success;
+        fence_before(success_order);
+        __asm__ __volatile__
+        (
+            "li %1, 0\n\t"
+            "lharx %0,%y2\n\t"
+            "cmpw %0, %3\n\t"
+            "bne- 1f\n\t"
+            "sthcx. %4,%y2\n\t"
+            "bne- 1f\n\t"
+            "li %1, 1\n\t"
+            "1:\n\t"
+            : "=&b" (expected), "=&b" (success), "+Z" (storage)
+            : "b" (expected), "b" (desired)
+            : "cr0"
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        int success;
+        fence_before(success_order);
+        __asm__ __volatile__
+        (
+            "li %1, 0\n\t"
+            "0: lharx %0,%y2\n\t"
+            "cmpw %0, %3\n\t"
+            "bne- 1f\n\t"
+            "sthcx. %4,%y2\n\t"
+            "bne- 0b\n\t"
+            "li %1, 1\n\t"
+            "1:\n\t"
+            : "=&b" (expected), "=&b" (success), "+Z" (storage)
+            : "b" (expected), "b" (desired)
+            : "cr0"
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lharx %0,%y2\n\t"
+            "add %1,%0,%3\n\t"
+            "sthcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lharx %0,%y2\n\t"
+            "sub %1,%0,%3\n\t"
+            "sthcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lharx %0,%y2\n\t"
+            "and %1,%0,%3\n\t"
+            "sthcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lharx %0,%y2\n\t"
+            "or %1,%0,%3\n\t"
+            "sthcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lharx %0,%y2\n\t"
+            "xor %1,%0,%3\n\t"
+            "sthcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!exchange(storage, (storage_type)1, order);
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        store(storage, (storage_type)0, order);
+    }
+};
+
+#else // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
+
+template< >
+struct operations< 2u, false > :
+    public operations< 4u, false >
+{
+    typedef operations< 4u, false > base_type;
+    typedef base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "add %1,%0,%3\n\t"
+            "rlwinm %1, %1, 0, 0xffff\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "sub %1,%0,%3\n\t"
+            "rlwinm %1, %1, 0, 0xffff\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+};
+
+template< >
+struct operations< 2u, true > :
+    public operations< 4u, true >
+{
+    typedef operations< 4u, true > base_type;
+    typedef base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "add %1,%0,%3\n\t"
+            "extsh %1, %1\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "lwarx %0,%y2\n\t"
+            "sub %1,%0,%3\n\t"
+            "extsh %1, %1\n\t"
+            "stwcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+};
+
+#endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
+
+#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
+
+template< bool Signed >
+struct operations< 8u, Signed > :
+    public gcc_ppc_operations_base
+{
+    typedef typename storage_traits< 8u >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 8u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "std %1, %0\n\t"
+            : "+m" (storage)
+            : "r" (v)
+        );
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v;
+        if (order == memory_order_seq_cst)
+            __asm__ __volatile__ ("sync" ::: "memory");
+        if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u)
+        {
+            __asm__ __volatile__
+            (
+                "ld %0, %1\n\t"
+                "cmpd %0, %0\n\t"
+                "bne- 1f\n\t"
+                "1:\n\t"
+                "isync\n\t"
+                : "=&b" (v)
+                : "m" (storage)
+                : "cr0", "memory"
+            );
+        }
+        else
+        {
+            __asm__ __volatile__
+            (
+                "ld %0, %1\n\t"
+                : "=&b" (v)
+                : "m" (storage)
+            );
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "ldarx %0,%y1\n\t"
+            "stdcx. %2,%y1\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "+Z" (storage)
+            : "b" (v)
+            : "cr0"
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        int success;
+        fence_before(success_order);
+        __asm__ __volatile__
+        (
+            "li %1, 0\n\t"
+            "ldarx %0,%y2\n\t"
+            "cmpd %0, %3\n\t"
+            "bne- 1f\n\t"
+            "stdcx. %4,%y2\n\t"
+            "bne- 1f\n\t"
+            "li %1, 1\n\t"
+            "1:"
+            : "=&b" (expected), "=&b" (success), "+Z" (storage)
+            : "b" (expected), "b" (desired)
+            : "cr0"
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        int success;
+        fence_before(success_order);
+        __asm__ __volatile__
+        (
+            "li %1, 0\n\t"
+            "0: ldarx %0,%y2\n\t"
+            "cmpd %0, %3\n\t"
+            "bne- 1f\n\t"
+            "stdcx. %4,%y2\n\t"
+            "bne- 0b\n\t"
+            "li %1, 1\n\t"
+            "1:\n\t"
+            : "=&b" (expected), "=&b" (success), "+Z" (storage)
+            : "b" (expected), "b" (desired)
+            : "cr0"
+        );
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        return !!success;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "ldarx %0,%y2\n\t"
+            "add %1,%0,%3\n\t"
+            "stdcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "ldarx %0,%y2\n\t"
+            "sub %1,%0,%3\n\t"
+            "stdcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "ldarx %0,%y2\n\t"
+            "and %1,%0,%3\n\t"
+            "stdcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "ldarx %0,%y2\n\t"
+            "or %1,%0,%3\n\t"
+            "stdcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type original, result;
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "1:\n\t"
+            "ldarx %0,%y2\n\t"
+            "xor %1,%0,%3\n\t"
+            "stdcx. %1,%y2\n\t"
+            "bne- 1b\n\t"
+            : "=&b" (original), "=&b" (result), "+Z" (storage)
+            : "b" (v)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
+        );
+        fence_after(order);
+        return original;
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!exchange(storage, (storage_type)1, order);
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        store(storage, (storage_type)0, order);
+    }
+};
+
+#endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
+
+
+BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
+{
+    if (order != memory_order_relaxed)
+    {
+#if defined(__powerpc64__) || defined(__PPC64__)
+        if (order != memory_order_seq_cst)
+            __asm__ __volatile__ ("lwsync" ::: "memory");
+        else
+            __asm__ __volatile__ ("sync" ::: "memory");
+#else
+        __asm__ __volatile__ ("sync" ::: "memory");
+#endif
+    }
+}
+
+BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
+{
+    if (order != memory_order_relaxed)
+#if defined(__ibmxl__) || defined(__IBMCPP__)
+        __fence();
+#else
+        __asm__ __volatile__ ("" ::: "memory");
+#endif
+}
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_gcc_ppc_common.hpp b/ThirdParty/boost/atomic/detail/ops_gcc_ppc_common.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e5c9303bf74edd8d33a8136cd16e532665c54a3c
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_gcc_ppc_common.hpp
@@ -0,0 +1,70 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_gcc_ppc_common.hpp
+ *
+ * This header contains basic utilities for gcc PowerPC backend.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_COMMON_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_COMMON_HPP_INCLUDED_
+
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+// The implementation below uses information from this document:
+// http://www.rdrop.com/users/paulmck/scalability/paper/N2745r.2010.02.19a.html
+
+// A note about memory_order_consume. Technically, this architecture allows to avoid
+// unnecessary memory barrier after consume load since it supports data dependency ordering.
+// However, some compiler optimizations may break a seemingly valid code relying on data
+// dependency tracking by injecting bogus branches to aid out of order execution.
+// This may happen not only in Boost.Atomic code but also in user's code, which we have no
+// control of. See this thread: http://lists.boost.org/Archives/boost/2014/06/213890.php.
+// For this reason we promote memory_order_consume to memory_order_acquire.
+
+struct gcc_ppc_operations_base
+{
+    static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false;
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
+
+    static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT
+    {
+#if defined(__powerpc64__) || defined(__PPC64__)
+        if (order == memory_order_seq_cst)
+            __asm__ __volatile__ ("sync" ::: "memory");
+        else if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u)
+            __asm__ __volatile__ ("lwsync" ::: "memory");
+#else
+        if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u)
+            __asm__ __volatile__ ("sync" ::: "memory");
+#endif
+    }
+
+    static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT
+    {
+        if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u)
+            __asm__ __volatile__ ("isync" ::: "memory");
+    }
+};
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_PPC_COMMON_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_gcc_sparc.hpp b/ThirdParty/boost/atomic/detail/ops_gcc_sparc.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3bd968d2d06454e3bc9a98f7d27c085ef3fa607a
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_gcc_sparc.hpp
@@ -0,0 +1,240 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2010 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_gcc_sparc.hpp
+ *
+ * This header contains implementation of the \c operations template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_SPARC_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_GCC_SPARC_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/operations_fwd.hpp>
+#include <boost/atomic/capabilities.hpp>
+#include <boost/atomic/detail/ops_cas_based.hpp>
+#include <boost/atomic/detail/ops_extending_cas_based.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+struct gcc_sparc_cas_base
+{
+    static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true;
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
+
+    static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT
+    {
+        if (order == memory_order_seq_cst)
+            __asm__ __volatile__ ("membar #Sync" ::: "memory");
+        else if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u)
+            __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory");
+    }
+
+    static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT
+    {
+        if (order == memory_order_seq_cst)
+            __asm__ __volatile__ ("membar #Sync" ::: "memory");
+        else if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u)
+            __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory");
+    }
+
+    static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
+    {
+        if (order == memory_order_seq_cst)
+            __asm__ __volatile__ ("membar #Sync" ::: "memory");
+    }
+};
+
+template< bool Signed >
+struct gcc_sparc_cas32 :
+    public gcc_sparc_cas_base
+{
+    typedef typename storage_traits< 4u >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 4u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        storage = v;
+        fence_after_store(order);
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v = storage;
+        fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        fence_before(success_order);
+        storage_type previous = expected;
+        __asm__ __volatile__
+        (
+            "cas [%1], %2, %0"
+            : "+r" (desired)
+            : "r" (&storage), "r" (previous)
+            : "memory"
+        );
+        const bool success = (desired == previous);
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        expected = desired;
+        return success;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        return compare_exchange_strong(storage, expected, desired, success_order, failure_order);
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        __asm__ __volatile__
+        (
+            "swap [%1], %0"
+            : "+r" (v)
+            : "r" (&storage)
+            : "memory"
+        );
+        fence_after(order);
+        return v;
+    }
+};
+
+template< bool Signed >
+struct operations< 4u, Signed > :
+    public cas_based_operations< gcc_sparc_cas32< Signed > >
+{
+};
+
+template< bool Signed >
+struct operations< 1u, Signed > :
+    public extending_cas_based_operations< operations< 4u, Signed >, 1u, Signed >
+{
+};
+
+template< bool Signed >
+struct operations< 2u, Signed > :
+    public extending_cas_based_operations< operations< 4u, Signed >, 2u, Signed >
+{
+};
+
+template< bool Signed >
+struct gcc_sparc_cas64 :
+    public gcc_sparc_cas_base
+{
+    typedef typename storage_traits< 8u >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 8u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before(order);
+        storage = v;
+        fence_after_store(order);
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v = storage;
+        fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        fence_before(success_order);
+        storage_type previous = expected;
+        __asm__ __volatile__
+        (
+            "casx [%1], %2, %0"
+            : "+r" (desired)
+            : "r" (&storage), "r" (previous)
+            : "memory"
+        );
+        const bool success = (desired == previous);
+        if (success)
+            fence_after(success_order);
+        else
+            fence_after(failure_order);
+        expected = desired;
+        return success;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        return compare_exchange_strong(storage, expected, desired, success_order, failure_order);
+    }
+};
+
+template< bool Signed >
+struct operations< 8u, Signed > :
+    public cas_based_operations< cas_based_exchange< gcc_sparc_cas64< Signed > > >
+{
+};
+
+
+BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
+{
+    switch (order)
+    {
+    case memory_order_release:
+        __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory");
+        break;
+    case memory_order_consume:
+    case memory_order_acquire:
+        __asm__ __volatile__ ("membar #LoadLoad | #LoadStore" ::: "memory");
+        break;
+    case memory_order_acq_rel:
+        __asm__ __volatile__ ("membar #LoadLoad | #LoadStore | #StoreStore" ::: "memory");
+        break;
+    case memory_order_seq_cst:
+        __asm__ __volatile__ ("membar #Sync" ::: "memory");
+        break;
+    case memory_order_relaxed:
+    default:
+        break;
+    }
+}
+
+BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
+{
+    if (order != memory_order_relaxed)
+        __asm__ __volatile__ ("" ::: "memory");
+}
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_SPARC_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_gcc_sync.hpp b/ThirdParty/boost/atomic/detail/ops_gcc_sync.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..279d1920b28662b6fcbfca4c27330840931f672c
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_gcc_sync.hpp
@@ -0,0 +1,240 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2011 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_gcc_sync.hpp
+ *
+ * This header contains implementation of the \c operations template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_SYNC_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_GCC_SYNC_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/operations_fwd.hpp>
+#include <boost/atomic/detail/ops_extending_cas_based.hpp>
+#include <boost/atomic/capabilities.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+struct gcc_sync_operations_base
+{
+    static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false;
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
+
+    static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT
+    {
+        if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u)
+            __sync_synchronize();
+    }
+
+    static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
+    {
+        if (order == memory_order_seq_cst)
+            __sync_synchronize();
+    }
+
+    static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT
+    {
+        if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_acquire) | static_cast< unsigned int >(memory_order_consume))) != 0u)
+            __sync_synchronize();
+    }
+};
+
+template< std::size_t Size, bool Signed >
+struct gcc_sync_operations :
+    public gcc_sync_operations_base
+{
+    typedef typename storage_traits< Size >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = storage_traits< Size >::alignment;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before_store(order);
+        storage = v;
+        fence_after_store(order);
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v = storage;
+        fence_after_load(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return __sync_fetch_and_add(&storage, v);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return __sync_fetch_and_sub(&storage, v);
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        // GCC docs mention that not all architectures may support full exchange semantics for this intrinsic. However, GCC's implementation of
+        // std::atomic<> uses this intrinsic unconditionally. We do so as well. In case if some architectures actually don't support this, we can always
+        // add a check here and fall back to a CAS loop.
+        if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u)
+            __sync_synchronize();
+        return __sync_lock_test_and_set(&storage, v);
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type expected2 = expected;
+        storage_type old_val = __sync_val_compare_and_swap(&storage, expected2, desired);
+
+        if (old_val == expected2)
+        {
+            return true;
+        }
+        else
+        {
+            expected = old_val;
+            return false;
+        }
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        return compare_exchange_strong(storage, expected, desired, success_order, failure_order);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return __sync_fetch_and_and(&storage, v);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return __sync_fetch_and_or(&storage, v);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return __sync_fetch_and_xor(&storage, v);
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u)
+            __sync_synchronize();
+        return !!__sync_lock_test_and_set(&storage, 1);
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        __sync_lock_release(&storage);
+        if (order == memory_order_seq_cst)
+            __sync_synchronize();
+    }
+};
+
+#if BOOST_ATOMIC_INT8_LOCK_FREE > 0
+template< bool Signed >
+struct operations< 1u, Signed > :
+#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1)
+    public gcc_sync_operations< 1u, Signed >
+#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)
+    public extending_cas_based_operations< gcc_sync_operations< 2u, Signed >, 1u, Signed >
+#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
+    public extending_cas_based_operations< gcc_sync_operations< 4u, Signed >, 1u, Signed >
+#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
+    public extending_cas_based_operations< gcc_sync_operations< 8u, Signed >, 1u, Signed >
+#else
+    public extending_cas_based_operations< gcc_sync_operations< 16u, Signed >, 1u, Signed >
+#endif
+{
+};
+#endif
+
+#if BOOST_ATOMIC_INT16_LOCK_FREE > 0
+template< bool Signed >
+struct operations< 2u, Signed > :
+#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)
+    public gcc_sync_operations< 2u, Signed >
+#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
+    public extending_cas_based_operations< gcc_sync_operations< 4u, Signed >, 2u, Signed >
+#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
+    public extending_cas_based_operations< gcc_sync_operations< 8u, Signed >, 2u, Signed >
+#else
+    public extending_cas_based_operations< gcc_sync_operations< 16u, Signed >, 2u, Signed >
+#endif
+{
+};
+#endif
+
+#if BOOST_ATOMIC_INT32_LOCK_FREE > 0
+template< bool Signed >
+struct operations< 4u, Signed > :
+#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
+    public gcc_sync_operations< 4u, Signed >
+#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
+    public extending_cas_based_operations< gcc_sync_operations< 8u, Signed >, 4u, Signed >
+#else
+    public extending_cas_based_operations< gcc_sync_operations< 16u, Signed >, 4u, Signed >
+#endif
+{
+};
+#endif
+
+#if BOOST_ATOMIC_INT64_LOCK_FREE > 0
+template< bool Signed >
+struct operations< 8u, Signed > :
+#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
+    public gcc_sync_operations< 8u, Signed >
+#else
+    public extending_cas_based_operations< gcc_sync_operations< 16u, Signed >, 8u, Signed >
+#endif
+{
+};
+#endif
+
+#if BOOST_ATOMIC_INT128_LOCK_FREE > 0
+template< bool Signed >
+struct operations< 16u, Signed > :
+    public gcc_sync_operations< 16u, Signed >
+{
+};
+#endif
+
+BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
+{
+    if (order != memory_order_relaxed)
+        __sync_synchronize();
+}
+
+BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
+{
+    if (order != memory_order_relaxed)
+        __asm__ __volatile__ ("" ::: "memory");
+}
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_SYNC_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_gcc_x86.hpp b/ThirdParty/boost/atomic/detail/ops_gcc_x86.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..66336952e01dc2a789d3d9b1104b408a66186a41
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_gcc_x86.hpp
@@ -0,0 +1,559 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2012 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_gcc_x86.hpp
+ *
+ * This header contains implementation of the \c operations template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_X86_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_GCC_X86_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/operations_fwd.hpp>
+#include <boost/atomic/capabilities.hpp>
+#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) || defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)
+#include <boost/atomic/detail/ops_gcc_x86_dcas.hpp>
+#include <boost/atomic/detail/ops_cas_based.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+struct gcc_x86_operations_base
+{
+    static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false;
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
+
+    static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT
+    {
+        if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u)
+            __asm__ __volatile__ ("" ::: "memory");
+    }
+
+    static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT
+    {
+        if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u)
+            __asm__ __volatile__ ("" ::: "memory");
+    }
+};
+
+template< std::size_t Size, bool Signed, typename Derived >
+struct gcc_x86_operations :
+    public gcc_x86_operations_base
+{
+    typedef typename storage_traits< Size >::type storage_type;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        if (order != memory_order_seq_cst)
+        {
+            fence_before(order);
+            storage = v;
+            fence_after(order);
+        }
+        else
+        {
+            Derived::exchange(storage, v, order);
+        }
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v = storage;
+        fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        return Derived::fetch_add(storage, -v, order);
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        return Derived::compare_exchange_strong(storage, expected, desired, success_order, failure_order);
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!Derived::exchange(storage, (storage_type)1, order);
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        store(storage, (storage_type)0, order);
+    }
+};
+
+template< bool Signed >
+struct operations< 1u, Signed > :
+    public gcc_x86_operations< 1u, Signed, operations< 1u, Signed > >
+{
+    typedef gcc_x86_operations< 1u, Signed, operations< 1u, Signed > > base_type;
+    typedef typename base_type::storage_type storage_type;
+    typedef typename storage_traits< 4u >::type temp_storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 1u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 1u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; xaddb %0, %1"
+            : "+q" (v), "+m" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "xchgb %0, %1"
+            : "+q" (v), "+m" (storage)
+            :
+            : "memory"
+        );
+        return v;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type previous = expected;
+        bool success;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; cmpxchgb %3, %1"
+            : "+a" (previous), "+m" (storage), "=@ccz" (success)
+            : "q" (desired)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; cmpxchgb %3, %1\n\t"
+            "sete %2"
+            : "+a" (previous), "+m" (storage), "=q" (success)
+            : "q" (desired)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        expected = previous;
+        return success;
+    }
+
+#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, result)\
+    temp_storage_type new_val;\
+    __asm__ __volatile__\
+    (\
+        ".align 16\n\t"\
+        "1: mov %[arg], %2\n\t"\
+        op " %%al, %b2\n\t"\
+        "lock; cmpxchgb %b2, %[storage]\n\t"\
+        "jne 1b"\
+        : [res] "+a" (result), [storage] "+m" (storage), "=&q" (new_val)\
+        : [arg] "ir" ((temp_storage_type)argument)\
+        : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
+    )
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type res = storage;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("andb", v, res);
+        return res;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type res = storage;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("orb", v, res);
+        return res;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type res = storage;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("xorb", v, res);
+        return res;
+    }
+
+#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
+};
+
+template< bool Signed >
+struct operations< 2u, Signed > :
+    public gcc_x86_operations< 2u, Signed, operations< 2u, Signed > >
+{
+    typedef gcc_x86_operations< 2u, Signed, operations< 2u, Signed > > base_type;
+    typedef typename base_type::storage_type storage_type;
+    typedef typename storage_traits< 4u >::type temp_storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 2u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 2u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; xaddw %0, %1"
+            : "+q" (v), "+m" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "xchgw %0, %1"
+            : "+q" (v), "+m" (storage)
+            :
+            : "memory"
+        );
+        return v;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type previous = expected;
+        bool success;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; cmpxchgw %3, %1"
+            : "+a" (previous), "+m" (storage), "=@ccz" (success)
+            : "q" (desired)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; cmpxchgw %3, %1\n\t"
+            "sete %2"
+            : "+a" (previous), "+m" (storage), "=q" (success)
+            : "q" (desired)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        expected = previous;
+        return success;
+    }
+
+#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, result)\
+    temp_storage_type new_val;\
+    __asm__ __volatile__\
+    (\
+        ".align 16\n\t"\
+        "1: mov %[arg], %2\n\t"\
+        op " %%ax, %w2\n\t"\
+        "lock; cmpxchgw %w2, %[storage]\n\t"\
+        "jne 1b"\
+        : [res] "+a" (result), [storage] "+m" (storage), "=&q" (new_val)\
+        : [arg] "ir" ((temp_storage_type)argument)\
+        : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
+    )
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type res = storage;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("andw", v, res);
+        return res;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type res = storage;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("orw", v, res);
+        return res;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type res = storage;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("xorw", v, res);
+        return res;
+    }
+
+#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
+};
+
+template< bool Signed >
+struct operations< 4u, Signed > :
+    public gcc_x86_operations< 4u, Signed, operations< 4u, Signed > >
+{
+    typedef gcc_x86_operations< 4u, Signed, operations< 4u, Signed > > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 4u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; xaddl %0, %1"
+            : "+r" (v), "+m" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "xchgl %0, %1"
+            : "+r" (v), "+m" (storage)
+            :
+            : "memory"
+        );
+        return v;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type previous = expected;
+        bool success;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; cmpxchgl %3, %1"
+            : "+a" (previous), "+m" (storage), "=@ccz" (success)
+            : "r" (desired)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; cmpxchgl %3, %1\n\t"
+            "sete %2"
+            : "+a" (previous), "+m" (storage), "=q" (success)
+            : "r" (desired)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        expected = previous;
+        return success;
+    }
+
+#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, result)\
+    storage_type new_val;\
+    __asm__ __volatile__\
+    (\
+        ".align 16\n\t"\
+        "1: mov %[arg], %[new_val]\n\t"\
+        op " %%eax, %[new_val]\n\t"\
+        "lock; cmpxchgl %[new_val], %[storage]\n\t"\
+        "jne 1b"\
+        : [res] "+a" (result), [storage] "+m" (storage), [new_val] "=&r" (new_val)\
+        : [arg] "ir" (argument)\
+        : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
+    )
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type res = storage;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("andl", v, res);
+        return res;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type res = storage;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("orl", v, res);
+        return res;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type res = storage;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("xorl", v, res);
+        return res;
+    }
+
+#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
+};
+
+#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B)
+
+template< bool Signed >
+struct operations< 8u, Signed > :
+    public cas_based_operations< gcc_dcas_x86< Signed > >
+{
+};
+
+#elif defined(__x86_64__)
+
+template< bool Signed >
+struct operations< 8u, Signed > :
+    public gcc_x86_operations< 8u, Signed, operations< 8u, Signed > >
+{
+    typedef gcc_x86_operations< 8u, Signed, operations< 8u, Signed > > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 8u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "lock; xaddq %0, %1"
+            : "+r" (v), "+m" (storage)
+            :
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "xchgq %0, %1"
+            : "+r" (v), "+m" (storage)
+            :
+            : "memory"
+        );
+        return v;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type previous = expected;
+        bool success;
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; cmpxchgq %3, %1"
+            : "+a" (previous), "+m" (storage), "=@ccz" (success)
+            : "r" (desired)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; cmpxchgq %3, %1\n\t"
+            "sete %2"
+            : "+a" (previous), "+m" (storage), "=q" (success)
+            : "r" (desired)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        expected = previous;
+        return success;
+    }
+
+#define BOOST_ATOMIC_DETAIL_CAS_LOOP(op, argument, result)\
+    storage_type new_val;\
+    __asm__ __volatile__\
+    (\
+        ".align 16\n\t"\
+        "1: movq %[arg], %[new_val]\n\t"\
+        op " %%rax, %[new_val]\n\t"\
+        "lock; cmpxchgq %[new_val], %[storage]\n\t"\
+        "jne 1b"\
+        : [res] "+a" (result), [storage] "+m" (storage), [new_val] "=&r" (new_val)\
+        : [arg] "r" (argument)\
+        : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"\
+    )
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type res = storage;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("andq", v, res);
+        return res;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type res = storage;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("orq", v, res);
+        return res;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type res = storage;
+        BOOST_ATOMIC_DETAIL_CAS_LOOP("xorq", v, res);
+        return res;
+    }
+
+#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
+};
+
+#endif
+
+#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)
+
+template< bool Signed >
+struct operations< 16u, Signed > :
+    public cas_based_operations< gcc_dcas_x86_64< Signed > >
+{
+};
+
+#endif // defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)
+
+BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
+{
+    if (order == memory_order_seq_cst)
+    {
+        __asm__ __volatile__
+        (
+#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE)
+            "mfence\n"
+#else
+            "lock; addl $0, (%%esp)\n"
+#endif
+            ::: "memory"
+        );
+    }
+    else if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_acquire) | static_cast< unsigned int >(memory_order_release))) != 0u)
+    {
+        __asm__ __volatile__ ("" ::: "memory");
+    }
+}
+
+BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
+{
+    if (order != memory_order_relaxed)
+        __asm__ __volatile__ ("" ::: "memory");
+}
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_X86_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_gcc_x86_dcas.hpp b/ThirdParty/boost/atomic/detail/ops_gcc_x86_dcas.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f2711f4e42774aad2488c7634e06f31f3fe09a54
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_gcc_x86_dcas.hpp
@@ -0,0 +1,560 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2012 Tim Blechmann
+ * Copyright (c) 2014 - 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_gcc_x86_dcas.hpp
+ *
+ * This header contains implementation of the double-width CAS primitive for x86.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_X86_DCAS_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_GCC_X86_DCAS_HPP_INCLUDED_
+
+#include <boost/cstdint.hpp>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/string_ops.hpp>
+#include <boost/atomic/capabilities.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+// Note: In the 32-bit PIC code guarded with BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX below we have to avoid using memory
+// operand constraints because the compiler may choose to use ebx as the base register for that operand. At least, clang
+// is known to do that. For this reason we have to pre-compute a pointer to storage and pass it in edi. For the same reason
+// we cannot save ebx to the stack with a mov instruction, so we use esi as a scratch register and restore it afterwards.
+// Alternatively, we could push/pop the register to the stack, but exchanging the registers is faster.
+// The need to pass a pointer in edi is a bit wasteful because normally the memory operand would use a base pointer
+// with an offset (e.g. `this` + offset). But unfortunately, there seems to be no way around it.
+
+#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B)
+
+template< bool Signed >
+struct gcc_dcas_x86
+{
+    typedef typename storage_traits< 8u >::type storage_type;
+    typedef uint32_t BOOST_ATOMIC_DETAIL_MAY_ALIAS aliasing_uint32_t;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 8u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+    static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true;
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        if (BOOST_LIKELY((((uint32_t)&storage) & 0x00000007) == 0u))
+        {
+#if defined(__SSE__)
+            typedef float xmm_t __attribute__((__vector_size__(16)));
+            xmm_t xmm_scratch;
+            __asm__ __volatile__
+            (
+#if defined(__AVX__)
+                "vmovq %[value], %[xmm_scratch]\n\t"
+                "vmovq %[xmm_scratch], %[storage]\n\t"
+#elif defined(__SSE2__)
+                "movq %[value], %[xmm_scratch]\n\t"
+                "movq %[xmm_scratch], %[storage]\n\t"
+#else
+                "xorps %[xmm_scratch], %[xmm_scratch]\n\t"
+                "movlps %[value], %[xmm_scratch]\n\t"
+                "movlps %[xmm_scratch], %[storage]\n\t"
+#endif
+                : [storage] "=m" (storage), [xmm_scratch] "=x" (xmm_scratch)
+                : [value] "m" (v)
+                : "memory"
+            );
+#else
+            __asm__ __volatile__
+            (
+                "fildll %[value]\n\t"
+                "fistpll %[storage]\n\t"
+                : [storage] "=m" (storage)
+                : [value] "m" (v)
+                : "memory"
+            );
+#endif
+        }
+        else
+        {
+#if defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX)
+            __asm__ __volatile__
+            (
+                "xchgl %%ebx, %%esi\n\t"
+                "movl %%eax, %%ebx\n\t"
+                "movl (%[dest]), %%eax\n\t"
+                "movl 4(%[dest]), %%edx\n\t"
+                ".align 16\n\t"
+                "1: lock; cmpxchg8b (%[dest])\n\t"
+                "jne 1b\n\t"
+                "xchgl %%ebx, %%esi\n\t"
+                :
+                : "a" ((uint32_t)v), "c" ((uint32_t)(v >> 32)), [dest] "D" (&storage)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "edx", "memory"
+            );
+#else // defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX)
+            __asm__ __volatile__
+            (
+                "movl %[dest_lo], %%eax\n\t"
+                "movl %[dest_hi], %%edx\n\t"
+                ".align 16\n\t"
+                "1: lock; cmpxchg8b %[dest_lo]\n\t"
+                "jne 1b\n\t"
+                : [dest_lo] "=m" (storage), [dest_hi] "=m" (reinterpret_cast< volatile aliasing_uint32_t* >(&storage)[1])
+                : [value_lo] "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32))
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "eax", "edx", "memory"
+            );
+#endif // defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX)
+        }
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type value;
+
+        if (BOOST_LIKELY((((uint32_t)&storage) & 0x00000007) == 0u))
+        {
+#if defined(__SSE__)
+            typedef float xmm_t __attribute__((__vector_size__(16)));
+            xmm_t xmm_scratch;
+            __asm__ __volatile__
+            (
+#if defined(__AVX__)
+                "vmovq %[storage], %[xmm_scratch]\n\t"
+                "vmovq %[xmm_scratch], %[value]\n\t"
+#elif defined(__SSE2__)
+                "movq %[storage], %[xmm_scratch]\n\t"
+                "movq %[xmm_scratch], %[value]\n\t"
+#else
+                "xorps %[xmm_scratch], %[xmm_scratch]\n\t"
+                "movlps %[storage], %[xmm_scratch]\n\t"
+                "movlps %[xmm_scratch], %[value]\n\t"
+#endif
+                : [value] "=m" (value), [xmm_scratch] "=x" (xmm_scratch)
+                : [storage] "m" (storage)
+                : "memory"
+            );
+#else
+            __asm__ __volatile__
+            (
+                "fildll %[storage]\n\t"
+                "fistpll %[value]\n\t"
+                : [value] "=m" (value)
+                : [storage] "m" (storage)
+                : "memory"
+            );
+#endif
+        }
+        else
+        {
+            // Note that despite const qualification cmpxchg8b below may issue a store to the storage. The storage value
+            // will not change, but this prevents the storage to reside in read-only memory.
+
+#if defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+
+            uint32_t value_bits[2];
+
+            // We don't care for comparison result here; the previous value will be stored into value anyway.
+            // Also we don't care for ebx and ecx values, they just have to be equal to eax and edx before cmpxchg8b.
+            __asm__ __volatile__
+            (
+                "movl %%ebx, %%eax\n\t"
+                "movl %%ecx, %%edx\n\t"
+                "lock; cmpxchg8b %[storage]\n\t"
+                : "=&a" (value_bits[0]), "=&d" (value_bits[1])
+                : [storage] "m" (storage)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+            BOOST_ATOMIC_DETAIL_MEMCPY(&value, value_bits, sizeof(value));
+
+#else // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+
+            // We don't care for comparison result here; the previous value will be stored into value anyway.
+            // Also we don't care for ebx and ecx values, they just have to be equal to eax and edx before cmpxchg8b.
+            __asm__ __volatile__
+            (
+                "movl %%ebx, %%eax\n\t"
+                "movl %%ecx, %%edx\n\t"
+                "lock; cmpxchg8b %[storage]\n\t"
+                : "=&A" (value)
+                : [storage] "m" (storage)
+                : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+            );
+
+#endif // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+        }
+
+        return value;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
+    {
+#if defined(__clang__)
+
+        // Clang cannot allocate eax:edx register pairs but it has sync intrinsics
+        storage_type old_expected = expected;
+        expected = __sync_val_compare_and_swap(&storage, old_expected, desired);
+        return expected == old_expected;
+
+#elif defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX)
+
+        bool success;
+
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "xchgl %%ebx, %%esi\n\t"
+            "lock; cmpxchg8b (%[dest])\n\t"
+            "xchgl %%ebx, %%esi\n\t"
+            : "+A" (expected), [success] "=@ccz" (success)
+            : "S" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32)), [dest] "D" (&storage)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "xchgl %%ebx, %%esi\n\t"
+            "lock; cmpxchg8b (%[dest])\n\t"
+            "xchgl %%ebx, %%esi\n\t"
+            "sete %[success]\n\t"
+            : "+A" (expected), [success] "=qm" (success)
+            : "S" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32)), [dest] "D" (&storage)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+
+        return success;
+
+#else // defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX)
+
+        bool success;
+
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; cmpxchg8b %[dest]\n\t"
+            : "+A" (expected), [dest] "+m" (storage), [success] "=@ccz" (success)
+            : "b" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32))
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; cmpxchg8b %[dest]\n\t"
+            "sete %[success]\n\t"
+            : "+A" (expected), [dest] "+m" (storage), [success] "=qm" (success)
+            : "b" ((uint32_t)desired), "c" ((uint32_t)(desired >> 32))
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+
+        return success;
+
+#endif // defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX)
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        return compare_exchange_strong(storage, expected, desired, success_order, failure_order);
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX)
+#if defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+
+        uint32_t old_bits[2];
+        __asm__ __volatile__
+        (
+            "xchgl %%ebx, %%esi\n\t"
+            "movl (%[dest]), %%eax\n\t"
+            "movl 4(%[dest]), %%edx\n\t"
+            ".align 16\n\t"
+            "1: lock; cmpxchg8b (%[dest])\n\t"
+            "jne 1b\n\t"
+            "xchgl %%ebx, %%esi\n\t"
+            : "=a" (old_bits[0]), "=d" (old_bits[1])
+            : "S" ((uint32_t)v), "c" ((uint32_t)(v >> 32)), [dest] "D" (&storage)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+
+        storage_type old_value;
+        BOOST_ATOMIC_DETAIL_MEMCPY(&old_value, old_bits, sizeof(old_value));
+        return old_value;
+
+#else // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+
+        storage_type old_value;
+        __asm__ __volatile__
+        (
+            "xchgl %%ebx, %%esi\n\t"
+            "movl (%[dest]), %%eax\n\t"
+            "movl 4(%[dest]), %%edx\n\t"
+            ".align 16\n\t"
+            "1: lock; cmpxchg8b (%[dest])\n\t"
+            "jne 1b\n\t"
+            "xchgl %%ebx, %%esi\n\t"
+            : "=A" (old_value)
+            : "S" ((uint32_t)v), "c" ((uint32_t)(v >> 32)), [dest] "D" (&storage)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        return old_value;
+
+#endif // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+#else // defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX)
+#if defined(__MINGW32__) && ((__GNUC__+0) * 100 + (__GNUC_MINOR__+0)) < 407
+
+        // MinGW gcc up to 4.6 has problems with allocating registers in the asm blocks below
+        uint32_t old_bits[2];
+        __asm__ __volatile__
+        (
+            "movl (%[dest]), %%eax\n\t"
+            "movl 4(%[dest]), %%edx\n\t"
+            ".align 16\n\t"
+            "1: lock; cmpxchg8b (%[dest])\n\t"
+            "jne 1b\n\t"
+            : "=&a" (old_bits[0]), "=&d" (old_bits[1])
+            : "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)), [dest] "DS" (&storage)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+
+        storage_type old_value;
+        BOOST_ATOMIC_DETAIL_MEMCPY(&old_value, old_bits, sizeof(old_value));
+        return old_value;
+
+#elif defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+
+        uint32_t old_bits[2];
+        __asm__ __volatile__
+        (
+            "movl %[dest_lo], %%eax\n\t"
+            "movl %[dest_hi], %%edx\n\t"
+            ".align 16\n\t"
+            "1: lock; cmpxchg8b %[dest_lo]\n\t"
+            "jne 1b\n\t"
+            : "=&a" (old_bits[0]), "=&d" (old_bits[1]), [dest_lo] "+m" (storage), [dest_hi] "+m" (reinterpret_cast< volatile aliasing_uint32_t* >(&storage)[1])
+            : "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32))
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+
+        storage_type old_value;
+        BOOST_ATOMIC_DETAIL_MEMCPY(&old_value, old_bits, sizeof(old_value));
+        return old_value;
+
+#else // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+
+        storage_type old_value;
+        __asm__ __volatile__
+        (
+            "movl %[dest_lo], %%eax\n\t"
+            "movl %[dest_hi], %%edx\n\t"
+            ".align 16\n\t"
+            "1: lock; cmpxchg8b %[dest_lo]\n\t"
+            "jne 1b\n\t"
+            : "=&A" (old_value), [dest_lo] "+m" (storage), [dest_hi] "+m" (reinterpret_cast< volatile aliasing_uint32_t* >(&storage)[1])
+            : "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32))
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+        return old_value;
+
+#endif // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+#endif // defined(BOOST_ATOMIC_DETAIL_X86_ASM_PRESERVE_EBX)
+    }
+};
+
+#endif // defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B)
+
+#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)
+
+template< bool Signed >
+struct gcc_dcas_x86_64
+{
+    typedef typename storage_traits< 16u >::type storage_type;
+    typedef uint64_t BOOST_ATOMIC_DETAIL_MAY_ALIAS aliasing_uint64_t;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 16u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 16u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+    static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true;
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        __asm__ __volatile__
+        (
+            "movq %[dest_lo], %%rax\n\t"
+            "movq %[dest_hi], %%rdx\n\t"
+            ".align 16\n\t"
+            "1: lock; cmpxchg16b %[dest_lo]\n\t"
+            "jne 1b\n\t"
+            : [dest_lo] "=m" (storage), [dest_hi] "=m" (reinterpret_cast< volatile aliasing_uint64_t* >(&storage)[1])
+            : "b" (reinterpret_cast< const aliasing_uint64_t* >(&v)[0]), "c" (reinterpret_cast< const aliasing_uint64_t* >(&v)[1])
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "rax", "rdx", "memory"
+        );
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        // Note that despite const qualification cmpxchg16b below may issue a store to the storage. The storage value
+        // will not change, but this prevents the storage to reside in read-only memory.
+
+#if defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+
+        uint64_t value_bits[2];
+
+        // We don't care for comparison result here; the previous value will be stored into value anyway.
+        // Also we don't care for rbx and rcx values, they just have to be equal to rax and rdx before cmpxchg16b.
+        __asm__ __volatile__
+        (
+            "movq %%rbx, %%rax\n\t"
+            "movq %%rcx, %%rdx\n\t"
+            "lock; cmpxchg16b %[storage]\n\t"
+            : "=&a" (value_bits[0]), "=&d" (value_bits[1])
+            : [storage] "m" (storage)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+
+        storage_type value;
+        BOOST_ATOMIC_DETAIL_MEMCPY(&value, value_bits, sizeof(value));
+        return value;
+
+#else // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+
+        storage_type value;
+
+        // We don't care for comparison result here; the previous value will be stored into value anyway.
+        // Also we don't care for rbx and rcx values, they just have to be equal to rax and rdx before cmpxchg16b.
+        __asm__ __volatile__
+        (
+            "movq %%rbx, %%rax\n\t"
+            "movq %%rcx, %%rdx\n\t"
+            "lock; cmpxchg16b %[storage]\n\t"
+            : "=&A" (value)
+            : [storage] "m" (storage)
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+
+        return value;
+
+#endif // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
+    {
+#if defined(__clang__)
+
+        // Clang cannot allocate rax:rdx register pairs but it has sync intrinsics
+        storage_type old_expected = expected;
+        expected = __sync_val_compare_and_swap(&storage, old_expected, desired);
+        return expected == old_expected;
+
+#elif defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+
+        // Some compilers can't allocate rax:rdx register pair either but also don't support 128-bit __sync_val_compare_and_swap
+        bool success;
+        __asm__ __volatile__
+        (
+            "lock; cmpxchg16b %[dest]\n\t"
+            "sete %[success]\n\t"
+            : [dest] "+m" (storage), "+a" (reinterpret_cast< aliasing_uint64_t* >(&expected)[0]), "+d" (reinterpret_cast< aliasing_uint64_t* >(&expected)[1]), [success] "=q" (success)
+            : "b" (reinterpret_cast< const aliasing_uint64_t* >(&desired)[0]), "c" (reinterpret_cast< const aliasing_uint64_t* >(&desired)[1])
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+
+        return success;
+
+#else // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+
+        bool success;
+
+#if defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; cmpxchg16b %[dest]\n\t"
+            : "+A" (expected), [dest] "+m" (storage), "=@ccz" (success)
+            : "b" (reinterpret_cast< const aliasing_uint64_t* >(&desired)[0]), "c" (reinterpret_cast< const aliasing_uint64_t* >(&desired)[1])
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#else // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+        __asm__ __volatile__
+        (
+            "lock; cmpxchg16b %[dest]\n\t"
+            "sete %[success]\n\t"
+            : "+A" (expected), [dest] "+m" (storage), [success] "=qm" (success)
+            : "b" (reinterpret_cast< const aliasing_uint64_t* >(&desired)[0]), "c" (reinterpret_cast< const aliasing_uint64_t* >(&desired)[1])
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+#endif // defined(BOOST_ATOMIC_DETAIL_ASM_HAS_FLAG_OUTPUTS)
+
+        return success;
+
+#endif // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        return compare_exchange_strong(storage, expected, desired, success_order, failure_order);
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+        uint64_t old_bits[2];
+        __asm__ __volatile__
+        (
+            "movq %[dest_lo], %%rax\n\t"
+            "movq %[dest_hi], %%rdx\n\t"
+            ".align 16\n\t"
+            "1: lock; cmpxchg16b %[dest_lo]\n\t"
+            "jne 1b\n\t"
+            : [dest_lo] "+m" (storage), [dest_hi] "+m" (reinterpret_cast< volatile aliasing_uint64_t* >(&storage)[1]), "=&a" (old_bits[0]), "=&d" (old_bits[1])
+            : "b" (reinterpret_cast< const aliasing_uint64_t* >(&v)[0]), "c" (reinterpret_cast< const aliasing_uint64_t* >(&v)[1])
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+
+        storage_type old_value;
+        BOOST_ATOMIC_DETAIL_MEMCPY(&old_value, old_bits, sizeof(old_value));
+        return old_value;
+#else // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+        storage_type old_value;
+        __asm__ __volatile__
+        (
+            "movq %[dest_lo], %%rax\n\t"
+            "movq %[dest_hi], %%rdx\n\t"
+            ".align 16\n\t"
+            "1: lock; cmpxchg16b %[dest_lo]\n\t"
+            "jne 1b\n\t"
+            : "=&A" (old_value), [dest_lo] "+m" (storage), [dest_hi] "+m" (reinterpret_cast< volatile aliasing_uint64_t* >(&storage)[1])
+            : "b" (reinterpret_cast< const aliasing_uint64_t* >(&v)[0]), "c" (reinterpret_cast< const aliasing_uint64_t* >(&v)[1])
+            : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC_COMMA "memory"
+        );
+
+        return old_value;
+#endif // defined(BOOST_ATOMIC_DETAIL_X86_NO_ASM_AX_DX_PAIRS)
+    }
+};
+
+#endif // defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_X86_DCAS_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_linux_arm.hpp b/ThirdParty/boost/atomic/detail/ops_linux_arm.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..41c350c9b208b3af56bb74903871f9df4244d65f
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_linux_arm.hpp
@@ -0,0 +1,180 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009, 2011 Helge Bahmann
+ * Copyright (c) 2009 Phil Endecott
+ * Copyright (c) 2013 Tim Blechmann
+ * Linux-specific code by Phil Endecott
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_linux_arm.hpp
+ *
+ * This header contains implementation of the \c operations template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_LINUX_ARM_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_LINUX_ARM_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/operations_fwd.hpp>
+#include <boost/atomic/capabilities.hpp>
+#include <boost/atomic/detail/ops_cas_based.hpp>
+#include <boost/atomic/detail/ops_extending_cas_based.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+// Different ARM processors have different atomic instructions.  In particular,
+// architecture versions before v6 (which are still in widespread use, e.g. the
+// Intel/Marvell XScale chips like the one in the NSLU2) have only atomic swap.
+// On Linux the kernel provides some support that lets us abstract away from
+// these differences: it provides emulated CAS and barrier functions at special
+// addresses that are guaranteed not to be interrupted by the kernel.  Using
+// this facility is slightly slower than inline assembler would be, but much
+// faster than a system call.
+//
+// While this emulated CAS is "strong" in the sense that it does not fail
+// "spuriously" (i.e.: it never fails to perform the exchange when the value
+// found equals the value expected), it does not return the found value on
+// failure. To satisfy the atomic API, compare_exchange_{weak|strong} must
+// return the found value on failure, and we have to manually load this value
+// after the emulated CAS reports failure. This in turn introduces a race
+// between the CAS failing (due to the "wrong" value being found) and subsequently
+// loading (which might turn up the "right" value). From an application's
+// point of view this looks like "spurious failure", and therefore the
+// emulated CAS is only good enough to provide compare_exchange_weak
+// semantics.
+
+struct linux_arm_cas_base
+{
+    static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true;
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
+
+    static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT
+    {
+        if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u)
+            hardware_full_fence();
+    }
+
+    static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
+    {
+        if (order == memory_order_seq_cst)
+            hardware_full_fence();
+    }
+
+    static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT
+    {
+        if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u)
+            hardware_full_fence();
+    }
+
+    static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT
+    {
+        typedef void (*kernel_dmb_t)(void);
+        ((kernel_dmb_t)0xffff0fa0)();
+    }
+};
+
+template< bool Signed >
+struct linux_arm_cas :
+    public linux_arm_cas_base
+{
+    typedef typename storage_traits< 4u >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 4u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        fence_before_store(order);
+        storage = v;
+        fence_after_store(order);
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v = storage;
+        fence_after_load(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        while (true)
+        {
+            storage_type tmp = expected;
+            if (compare_exchange_weak(storage, tmp, desired, success_order, failure_order))
+                return true;
+            if (tmp != expected)
+            {
+                expected = tmp;
+                return false;
+            }
+        }
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
+    {
+        typedef storage_type (*kernel_cmpxchg32_t)(storage_type oldval, storage_type newval, volatile storage_type* ptr);
+
+        if (((kernel_cmpxchg32_t)0xffff0fc0)(expected, desired, &storage) == 0)
+        {
+            return true;
+        }
+        else
+        {
+            expected = storage;
+            return false;
+        }
+    }
+};
+
+template< bool Signed >
+struct operations< 1u, Signed > :
+    public extending_cas_based_operations< cas_based_operations< cas_based_exchange< linux_arm_cas< Signed > > >, 1u, Signed >
+{
+};
+
+template< bool Signed >
+struct operations< 2u, Signed > :
+    public extending_cas_based_operations< cas_based_operations< cas_based_exchange< linux_arm_cas< Signed > > >, 2u, Signed >
+{
+};
+
+template< bool Signed >
+struct operations< 4u, Signed > :
+    public cas_based_operations< cas_based_exchange< linux_arm_cas< Signed > > >
+{
+};
+
+BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
+{
+    if (order != memory_order_relaxed)
+        linux_arm_cas_base::hardware_full_fence();
+}
+
+BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
+{
+    if (order != memory_order_relaxed)
+        __asm__ __volatile__ ("" ::: "memory");
+}
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_LINUX_ARM_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_msvc_arm.hpp b/ThirdParty/boost/atomic/detail/ops_msvc_arm.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..fbae0a80ddd131d63f470439205aec8a54536ae6
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_msvc_arm.hpp
@@ -0,0 +1,824 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2012 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_msvc_arm.hpp
+ *
+ * This header contains implementation of the \c operations template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_MSVC_ARM_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_MSVC_ARM_HPP_INCLUDED_
+
+#include <intrin.h>
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/interlocked.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/operations_fwd.hpp>
+#include <boost/atomic/detail/type_traits/make_signed.hpp>
+#include <boost/atomic/capabilities.hpp>
+#include <boost/atomic/detail/ops_msvc_common.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#define BOOST_ATOMIC_DETAIL_ARM_LOAD8(p) __iso_volatile_load8((const volatile __int8*)(p))
+#define BOOST_ATOMIC_DETAIL_ARM_LOAD16(p) __iso_volatile_load16((const volatile __int16*)(p))
+#define BOOST_ATOMIC_DETAIL_ARM_LOAD32(p) __iso_volatile_load32((const volatile __int32*)(p))
+#define BOOST_ATOMIC_DETAIL_ARM_LOAD64(p) __iso_volatile_load64((const volatile __int64*)(p))
+#define BOOST_ATOMIC_DETAIL_ARM_STORE8(p, v) __iso_volatile_store8((volatile __int8*)(p), (__int8)(v))
+#define BOOST_ATOMIC_DETAIL_ARM_STORE16(p, v) __iso_volatile_store16((volatile __int16*)(p), (__int16)(v))
+#define BOOST_ATOMIC_DETAIL_ARM_STORE32(p, v) __iso_volatile_store32((volatile __int32*)(p), (__int32)(v))
+#define BOOST_ATOMIC_DETAIL_ARM_STORE64(p, v) __iso_volatile_store64((volatile __int64*)(p), (__int64)(v))
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+// A note about memory_order_consume. Technically, this architecture allows to avoid
+// unnecessary memory barrier after consume load since it supports data dependency ordering.
+// However, some compiler optimizations may break a seemingly valid code relying on data
+// dependency tracking by injecting bogus branches to aid out of order execution.
+// This may happen not only in Boost.Atomic code but also in user's code, which we have no
+// control of. See this thread: http://lists.boost.org/Archives/boost/2014/06/213890.php.
+// For this reason we promote memory_order_consume to memory_order_acquire.
+
+struct msvc_arm_operations_base
+{
+    static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false;
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
+
+    static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT
+    {
+        __dmb(0xB); // _ARM_BARRIER_ISH, see armintr.h from MSVC 11 and later
+    }
+
+    static BOOST_FORCEINLINE void fence_before_store(memory_order order) BOOST_NOEXCEPT
+    {
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+
+        if ((static_cast< unsigned int >(order) & static_cast< unsigned int >(memory_order_release)) != 0u)
+            hardware_full_fence();
+
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+    }
+
+    static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
+    {
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+
+        if (order == memory_order_seq_cst)
+            hardware_full_fence();
+
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+    }
+
+    static BOOST_FORCEINLINE void fence_after_load(memory_order order) BOOST_NOEXCEPT
+    {
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+
+        if ((static_cast< unsigned int >(order) & (static_cast< unsigned int >(memory_order_consume) | static_cast< unsigned int >(memory_order_acquire))) != 0u)
+            hardware_full_fence();
+
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+    }
+
+    static BOOST_FORCEINLINE BOOST_CONSTEXPR memory_order cas_common_order(memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        // Combine order flags together and promote memory_order_consume to memory_order_acquire
+        return static_cast< memory_order >(((static_cast< unsigned int >(failure_order) | static_cast< unsigned int >(success_order)) & ~static_cast< unsigned int >(memory_order_consume))
+            | (((static_cast< unsigned int >(failure_order) | static_cast< unsigned int >(success_order)) & static_cast< unsigned int >(memory_order_consume)) << 1u));
+    }
+};
+
+template< std::size_t Size, bool Signed, typename Derived >
+struct msvc_arm_operations :
+    public msvc_arm_operations_base
+{
+    typedef typename storage_traits< Size >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = storage_traits< Size >::alignment;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        typedef typename boost::atomics::detail::make_signed< storage_type >::type signed_storage_type;
+        return Derived::fetch_add(storage, static_cast< storage_type >(-static_cast< signed_storage_type >(v)), order);
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        return Derived::compare_exchange_strong(storage, expected, desired, success_order, failure_order);
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!Derived::exchange(storage, (storage_type)1, order);
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        Derived::store(storage, (storage_type)0, order);
+    }
+};
+
+template< bool Signed >
+struct operations< 1u, Signed > :
+    public msvc_arm_operations< 1u, Signed, operations< 1u, Signed > >
+{
+    typedef msvc_arm_operations< 1u, Signed, operations< 1u, Signed > > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before_store(order);
+        BOOST_ATOMIC_DETAIL_ARM_STORE8(&storage, v);
+        base_type::fence_after_store(order);
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v = BOOST_ATOMIC_DETAIL_ARM_LOAD8(&storage);
+        base_type::fence_after_load(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8(&storage, v));
+            break;
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8(&storage, v));
+            break;
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        storage_type previous = expected, old_val;
+
+        switch (cas_common_order(success_order, failure_order))
+        {
+        case memory_order_relaxed:
+            old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_RELAXED(&storage, desired, previous));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_ACQUIRE(&storage, desired, previous));
+            break;
+        case memory_order_release:
+            old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8_RELEASE(&storage, desired, previous));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8(&storage, desired, previous));
+            break;
+        }
+        expected = old_val;
+
+        return (previous == old_val);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8(&storage, v));
+            break;
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8(&storage, v));
+            break;
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8(&storage, v));
+            break;
+        }
+        return v;
+    }
+};
+
+template< bool Signed >
+struct operations< 2u, Signed > :
+    public msvc_arm_operations< 2u, Signed, operations< 2u, Signed > >
+{
+    typedef msvc_arm_operations< 2u, Signed, operations< 2u, Signed > > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before_store(order);
+        BOOST_ATOMIC_DETAIL_ARM_STORE16(&storage, v);
+        base_type::fence_after_store(order);
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v = BOOST_ATOMIC_DETAIL_ARM_LOAD16(&storage);
+        base_type::fence_after_load(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16(&storage, v));
+            break;
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16(&storage, v));
+            break;
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        storage_type previous = expected, old_val;
+
+        switch (cas_common_order(success_order, failure_order))
+        {
+        case memory_order_relaxed:
+            old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_RELAXED(&storage, desired, previous));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_ACQUIRE(&storage, desired, previous));
+            break;
+        case memory_order_release:
+            old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16_RELEASE(&storage, desired, previous));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16(&storage, desired, previous));
+            break;
+        }
+        expected = old_val;
+
+        return (previous == old_val);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16(&storage, v));
+            break;
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16(&storage, v));
+            break;
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16(&storage, v));
+            break;
+        }
+        return v;
+    }
+};
+
+template< bool Signed >
+struct operations< 4u, Signed > :
+    public msvc_arm_operations< 4u, Signed, operations< 4u, Signed > >
+{
+    typedef msvc_arm_operations< 4u, Signed, operations< 4u, Signed > > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before_store(order);
+        BOOST_ATOMIC_DETAIL_ARM_STORE32(&storage, v);
+        base_type::fence_after_store(order);
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v = BOOST_ATOMIC_DETAIL_ARM_LOAD32(&storage);
+        base_type::fence_after_load(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&storage, v));
+            break;
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&storage, v));
+            break;
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        storage_type previous = expected, old_val;
+
+        switch (cas_common_order(success_order, failure_order))
+        {
+        case memory_order_relaxed:
+            old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_RELAXED(&storage, desired, previous));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_ACQUIRE(&storage, desired, previous));
+            break;
+        case memory_order_release:
+            old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_RELEASE(&storage, desired, previous));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&storage, desired, previous));
+            break;
+        }
+        expected = old_val;
+
+        return (previous == old_val);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND(&storage, v));
+            break;
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR(&storage, v));
+            break;
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR(&storage, v));
+            break;
+        }
+        return v;
+    }
+};
+
+template< bool Signed >
+struct operations< 8u, Signed > :
+    public msvc_arm_operations< 8u, Signed, operations< 8u, Signed > >
+{
+    typedef msvc_arm_operations< 8u, Signed, operations< 8u, Signed > > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before_store(order);
+        BOOST_ATOMIC_DETAIL_ARM_STORE64(&storage, v);
+        base_type::fence_after_store(order);
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v = BOOST_ATOMIC_DETAIL_ARM_LOAD64(&storage);
+        base_type::fence_after_load(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(&storage, v));
+            break;
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(&storage, v));
+            break;
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        storage_type previous = expected, old_val;
+
+        switch (cas_common_order(success_order, failure_order))
+        {
+        case memory_order_relaxed:
+            old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_RELAXED(&storage, desired, previous));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_ACQUIRE(&storage, desired, previous));
+            break;
+        case memory_order_release:
+            old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64_RELEASE(&storage, desired, previous));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(&storage, desired, previous));
+            break;
+        }
+        expected = old_val;
+
+        return (previous == old_val);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64(&storage, v));
+            break;
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64(&storage, v));
+            break;
+        }
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        switch (order)
+        {
+        case memory_order_relaxed:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64_RELAXED(&storage, v));
+            break;
+        case memory_order_consume:
+        case memory_order_acquire:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64_ACQUIRE(&storage, v));
+            break;
+        case memory_order_release:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64_RELEASE(&storage, v));
+            break;
+        case memory_order_acq_rel:
+        case memory_order_seq_cst:
+        default:
+            v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64(&storage, v));
+            break;
+        }
+        return v;
+    }
+};
+
+
+BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
+{
+    BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+    if (order != memory_order_relaxed)
+        msvc_arm_operations_base::hardware_full_fence();
+    BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+}
+
+BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
+{
+    if (order != memory_order_relaxed)
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+}
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#undef BOOST_ATOMIC_DETAIL_ARM_LOAD8
+#undef BOOST_ATOMIC_DETAIL_ARM_LOAD16
+#undef BOOST_ATOMIC_DETAIL_ARM_LOAD32
+#undef BOOST_ATOMIC_DETAIL_ARM_LOAD64
+#undef BOOST_ATOMIC_DETAIL_ARM_STORE8
+#undef BOOST_ATOMIC_DETAIL_ARM_STORE16
+#undef BOOST_ATOMIC_DETAIL_ARM_STORE32
+#undef BOOST_ATOMIC_DETAIL_ARM_STORE64
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_MSVC_ARM_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_msvc_common.hpp b/ThirdParty/boost/atomic/detail/ops_msvc_common.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..8c5120760b372639aa2c96f1d5046281c9140171
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_msvc_common.hpp
@@ -0,0 +1,40 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2012 Tim Blechmann
+ * Copyright (c) 2014, 2019 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_msvc_common.hpp
+ *
+ * This header contains common tools for MSVC implementation of the \c operations template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_MSVC_COMMON_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_MSVC_COMMON_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+// Define compiler barriers
+#if defined(__INTEL_COMPILER)
+#define BOOST_ATOMIC_DETAIL_COMPILER_BARRIER() __memory_barrier()
+#elif defined(__clang__)
+#define BOOST_ATOMIC_DETAIL_COMPILER_BARRIER() __atomic_signal_fence(__ATOMIC_SEQ_CST)
+#elif defined(_MSC_VER) && !defined(_WIN32_WCE)
+extern "C" void _ReadWriteBarrier(void);
+#pragma intrinsic(_ReadWriteBarrier)
+#define BOOST_ATOMIC_DETAIL_COMPILER_BARRIER() _ReadWriteBarrier()
+#endif
+
+#ifndef BOOST_ATOMIC_DETAIL_COMPILER_BARRIER
+#define BOOST_ATOMIC_DETAIL_COMPILER_BARRIER()
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_MSVC_COMMON_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_msvc_x86.hpp b/ThirdParty/boost/atomic/detail/ops_msvc_x86.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..023b67fd104a7fad742c444aeb6e1c809d4a1956
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_msvc_x86.hpp
@@ -0,0 +1,908 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2012 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_msvc_x86.hpp
+ *
+ * This header contains implementation of the \c operations template.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_MSVC_X86_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_MSVC_X86_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/interlocked.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/operations_fwd.hpp>
+#include <boost/atomic/detail/type_traits/make_signed.hpp>
+#include <boost/atomic/capabilities.hpp>
+#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B) || defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)
+#include <boost/cstdint.hpp>
+#include <boost/atomic/detail/ops_cas_based.hpp>
+#endif
+#include <boost/atomic/detail/ops_msvc_common.hpp>
+#if !defined(_M_IX86) && !(defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8) && defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16))
+#include <boost/atomic/detail/ops_extending_cas_based.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(BOOST_MSVC)
+#pragma warning(push)
+// frame pointer register 'ebx' modified by inline assembly code. See the note below.
+#pragma warning(disable: 4731)
+#endif
+
+#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE)
+extern "C" void _mm_mfence(void);
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_mm_mfence)
+#endif
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+/*
+ * Implementation note for asm blocks.
+ *
+ * http://msdn.microsoft.com/en-us/data/k1a8ss06%28v=vs.105%29
+ *
+ * Some SSE types require eight-byte stack alignment, forcing the compiler to emit dynamic stack-alignment code.
+ * To be able to access both the local variables and the function parameters after the alignment, the compiler
+ * maintains two frame pointers. If the compiler performs frame pointer omission (FPO), it will use EBP and ESP.
+ * If the compiler does not perform FPO, it will use EBX and EBP. To ensure code runs correctly, do not modify EBX
+ * in asm code if the function requires dynamic stack alignment as it could modify the frame pointer.
+ * Either move the eight-byte aligned types out of the function, or avoid using EBX.
+ *
+ * Since we have no way of knowing that the compiler uses FPO, we have to always save and restore ebx
+ * whenever we have to clobber it. Additionally, we disable warning C4731 above so that the compiler
+ * doesn't spam about ebx use.
+ */
+
+struct msvc_x86_operations_base
+{
+    static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false;
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
+
+    static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_MFENCE)
+        _mm_mfence();
+#else
+        long tmp;
+        BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&tmp, 0);
+#endif
+    }
+
+    static BOOST_FORCEINLINE void fence_before(memory_order) BOOST_NOEXCEPT
+    {
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+    }
+
+    static BOOST_FORCEINLINE void fence_after(memory_order) BOOST_NOEXCEPT
+    {
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+    }
+
+    static BOOST_FORCEINLINE void fence_after_load(memory_order) BOOST_NOEXCEPT
+    {
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+
+        // On x86 and x86_64 there is no need for a hardware barrier,
+        // even if seq_cst memory order is requested, because all
+        // seq_cst writes are implemented with lock-prefixed operations
+        // or xchg which has implied lock prefix. Therefore normal loads
+        // are already ordered with seq_cst stores on these architectures.
+    }
+};
+
+template< std::size_t Size, bool Signed, typename Derived >
+struct msvc_x86_operations :
+    public msvc_x86_operations_base
+{
+    typedef typename storage_traits< Size >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = storage_traits< Size >::alignment;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        if (order != memory_order_seq_cst)
+        {
+            fence_before(order);
+            storage = v;
+            fence_after(order);
+        }
+        else
+        {
+            Derived::exchange(storage, v, order);
+        }
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type v = storage;
+        fence_after_load(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        typedef typename boost::atomics::detail::make_signed< storage_type >::type signed_storage_type;
+        return Derived::fetch_add(storage, static_cast< storage_type >(-static_cast< signed_storage_type >(v)), order);
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        return Derived::compare_exchange_strong(storage, expected, desired, success_order, failure_order);
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!Derived::exchange(storage, (storage_type)1, order);
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        store(storage, (storage_type)0, order);
+    }
+};
+
+template< bool Signed >
+struct operations< 4u, Signed > :
+    public msvc_x86_operations< 4u, Signed, operations< 4u, Signed > >
+{
+    typedef msvc_x86_operations< 4u, Signed, operations< 4u, Signed > > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&storage, v));
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&storage, v));
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type previous = expected;
+        storage_type old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&storage, desired, previous));
+        expected = old_val;
+        return (previous == old_val);
+    }
+
+#if defined(BOOST_ATOMIC_INTERLOCKED_AND)
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND(&storage, v));
+    }
+#else
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type res = storage;
+        while (!compare_exchange_strong(storage, res, res & v, order, memory_order_relaxed)) {}
+        return res;
+    }
+#endif
+
+#if defined(BOOST_ATOMIC_INTERLOCKED_OR)
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR(&storage, v));
+    }
+#else
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type res = storage;
+        while (!compare_exchange_strong(storage, res, res | v, order, memory_order_relaxed)) {}
+        return res;
+    }
+#endif
+
+#if defined(BOOST_ATOMIC_INTERLOCKED_XOR)
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR(&storage, v));
+    }
+#else
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        storage_type res = storage;
+        while (!compare_exchange_strong(storage, res, res ^ v, order, memory_order_relaxed)) {}
+        return res;
+    }
+#endif
+};
+
+#if defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8)
+
+template< bool Signed >
+struct operations< 1u, Signed > :
+    public msvc_x86_operations< 1u, Signed, operations< 1u, Signed > >
+{
+    typedef msvc_x86_operations< 1u, Signed, operations< 1u, Signed > > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8(&storage, v));
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE8(&storage, v));
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type previous = expected;
+        storage_type old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8(&storage, desired, previous));
+        expected = old_val;
+        return (previous == old_val);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND8(&storage, v));
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR8(&storage, v));
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR8(&storage, v));
+    }
+};
+
+#elif defined(_M_IX86)
+
+template< bool Signed >
+struct operations< 1u, Signed > :
+    public msvc_x86_operations< 1u, Signed, operations< 1u, Signed > >
+{
+    typedef msvc_x86_operations< 1u, Signed, operations< 1u, Signed > > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock xadd byte ptr [edx], al
+            mov v, al
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            xchg byte ptr [edx], al
+            mov v, al
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(success_order);
+        bool success;
+        __asm
+        {
+            mov esi, expected
+            mov edi, storage
+            movzx eax, byte ptr [esi]
+            movzx edx, desired
+            lock cmpxchg byte ptr [edi], dl
+            mov byte ptr [esi], al
+            sete success
+        };
+        // The success and failure fences are equivalent anyway
+        base_type::fence_after(success_order);
+        return success;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edi, storage
+            movzx ecx, v
+            xor edx, edx
+            movzx eax, byte ptr [edi]
+            align 16
+        again:
+            mov dl, al
+            and dl, cl
+            lock cmpxchg byte ptr [edi], dl
+            jne again
+            mov v, al
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edi, storage
+            movzx ecx, v
+            xor edx, edx
+            movzx eax, byte ptr [edi]
+            align 16
+        again:
+            mov dl, al
+            or dl, cl
+            lock cmpxchg byte ptr [edi], dl
+            jne again
+            mov v, al
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edi, storage
+            movzx ecx, v
+            xor edx, edx
+            movzx eax, byte ptr [edi]
+            align 16
+        again:
+            mov dl, al
+            xor dl, cl
+            lock cmpxchg byte ptr [edi], dl
+            jne again
+            mov v, al
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+};
+
+#else
+
+template< bool Signed >
+struct operations< 1u, Signed > :
+    public extending_cas_based_operations< operations< 4u, Signed >, 1u, Signed >
+{
+};
+
+#endif
+
+#if defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16)
+
+template< bool Signed >
+struct operations< 2u, Signed > :
+    public msvc_x86_operations< 2u, Signed, operations< 2u, Signed > >
+{
+    typedef msvc_x86_operations< 2u, Signed, operations< 2u, Signed > > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16(&storage, v));
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE16(&storage, v));
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type previous = expected;
+        storage_type old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16(&storage, desired, previous));
+        expected = old_val;
+        return (previous == old_val);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND16(&storage, v));
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR16(&storage, v));
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR16(&storage, v));
+    }
+};
+
+#elif defined(_M_IX86)
+
+template< bool Signed >
+struct operations< 2u, Signed > :
+    public msvc_x86_operations< 2u, Signed, operations< 2u, Signed > >
+{
+    typedef msvc_x86_operations< 2u, Signed, operations< 2u, Signed > > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            lock xadd word ptr [edx], ax
+            mov v, ax
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edx, storage
+            movzx eax, v
+            xchg word ptr [edx], ax
+            mov v, ax
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(success_order);
+        bool success;
+        __asm
+        {
+            mov esi, expected
+            mov edi, storage
+            movzx eax, word ptr [esi]
+            movzx edx, desired
+            lock cmpxchg word ptr [edi], dx
+            mov word ptr [esi], ax
+            sete success
+        };
+        // The success and failure fences are equivalent anyway
+        base_type::fence_after(success_order);
+        return success;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edi, storage
+            movzx ecx, v
+            xor edx, edx
+            movzx eax, word ptr [edi]
+            align 16
+        again:
+            mov dx, ax
+            and dx, cx
+            lock cmpxchg word ptr [edi], dx
+            jne again
+            mov v, ax
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edi, storage
+            movzx ecx, v
+            xor edx, edx
+            movzx eax, word ptr [edi]
+            align 16
+        again:
+            mov dx, ax
+            or dx, cx
+            lock cmpxchg word ptr [edi], dx
+            jne again
+            mov v, ax
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        __asm
+        {
+            mov edi, storage
+            movzx ecx, v
+            xor edx, edx
+            movzx eax, word ptr [edi]
+            align 16
+        again:
+            mov dx, ax
+            xor dx, cx
+            lock cmpxchg word ptr [edi], dx
+            jne again
+            mov v, ax
+        };
+        base_type::fence_after(order);
+        return v;
+    }
+};
+
+#else
+
+template< bool Signed >
+struct operations< 2u, Signed > :
+    public extending_cas_based_operations< operations< 4u, Signed >, 2u, Signed >
+{
+};
+
+#endif
+
+
+#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B)
+
+template< bool Signed >
+struct msvc_dcas_x86
+{
+    typedef typename storage_traits< 8u >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true;
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 8u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    // Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3A, 8.1.1. Guaranteed Atomic Operations:
+    //
+    // The Pentium processor (and newer processors since) guarantees that the following additional memory operations will always be carried out atomically:
+    // * Reading or writing a quadword aligned on a 64-bit boundary
+    //
+    // Luckily, the memory is almost always 8-byte aligned in our case because atomic<> uses 64 bit native types for storage and dynamic memory allocations
+    // have at least 8 byte alignment. The only unfortunate case is when atomic is placed on the stack and it is not 8-byte aligned (like on 32 bit Windows).
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+
+        storage_type volatile* p = &storage;
+        if (((uint32_t)p & 0x00000007) == 0)
+        {
+#if defined(_M_IX86_FP) && _M_IX86_FP >= 2
+#if defined(__AVX__)
+            __asm
+            {
+                mov edx, p
+                vmovq xmm4, v
+                vmovq qword ptr [edx], xmm4
+            };
+#else
+            __asm
+            {
+                mov edx, p
+                movq xmm4, v
+                movq qword ptr [edx], xmm4
+            };
+#endif
+#else
+            __asm
+            {
+                mov edx, p
+                fild v
+                fistp qword ptr [edx]
+            };
+#endif
+        }
+        else
+        {
+            uint32_t backup;
+            __asm
+            {
+                mov backup, ebx
+                mov edi, p
+                mov ebx, dword ptr [v]
+                mov ecx, dword ptr [v + 4]
+                mov eax, dword ptr [edi]
+                mov edx, dword ptr [edi + 4]
+                align 16
+            again:
+                lock cmpxchg8b qword ptr [edi]
+                jne again
+                mov ebx, backup
+            };
+        }
+
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+
+        storage_type const volatile* p = &storage;
+        storage_type value;
+
+        if (((uint32_t)p & 0x00000007) == 0)
+        {
+#if defined(_M_IX86_FP) && _M_IX86_FP >= 2
+#if defined(__AVX__)
+            __asm
+            {
+                mov edx, p
+                vmovq xmm4, qword ptr [edx]
+                vmovq value, xmm4
+            };
+#else
+            __asm
+            {
+                mov edx, p
+                movq xmm4, qword ptr [edx]
+                movq value, xmm4
+            };
+#endif
+#else
+            __asm
+            {
+                mov edx, p
+                fild qword ptr [edx]
+                fistp value
+            };
+#endif
+        }
+        else
+        {
+            // We don't care for comparison result here; the previous value will be stored into value anyway.
+            // Also we don't care for ebx and ecx values, they just have to be equal to eax and edx before cmpxchg8b.
+            __asm
+            {
+                mov edi, p
+                mov eax, ebx
+                mov edx, ecx
+                lock cmpxchg8b qword ptr [edi]
+                mov dword ptr [value], eax
+                mov dword ptr [value + 4], edx
+            };
+        }
+
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+
+        return value;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
+    {
+        // MSVC-11 in 32-bit mode sometimes generates messed up code without compiler barriers,
+        // even though the _InterlockedCompareExchange64 intrinsic already provides one.
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+
+        storage_type volatile* p = &storage;
+#if defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64)
+        const storage_type old_val = (storage_type)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(p, desired, expected);
+        const bool result = (old_val == expected);
+        expected = old_val;
+#else
+        bool result;
+        uint32_t backup;
+        __asm
+        {
+            mov backup, ebx
+            mov edi, p
+            mov esi, expected
+            mov ebx, dword ptr [desired]
+            mov ecx, dword ptr [desired + 4]
+            mov eax, dword ptr [esi]
+            mov edx, dword ptr [esi + 4]
+            lock cmpxchg8b qword ptr [edi]
+            mov dword ptr [esi], eax
+            mov dword ptr [esi + 4], edx
+            mov ebx, backup
+            sete result
+        };
+#endif
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+
+        return result;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        return compare_exchange_strong(storage, expected, desired, success_order, failure_order);
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+
+        storage_type volatile* p = &storage;
+        uint32_t backup;
+        __asm
+        {
+            mov backup, ebx
+            mov edi, p
+            mov ebx, dword ptr [v]
+            mov ecx, dword ptr [v + 4]
+            mov eax, dword ptr [edi]
+            mov edx, dword ptr [edi + 4]
+            align 16
+        again:
+            lock cmpxchg8b qword ptr [edi]
+            jne again
+            mov ebx, backup
+            mov dword ptr [v], eax
+            mov dword ptr [v + 4], edx
+        };
+
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+
+        return v;
+    }
+};
+
+template< bool Signed >
+struct operations< 8u, Signed > :
+    public cas_based_operations< msvc_dcas_x86< Signed > >
+{
+};
+
+#elif defined(_M_AMD64)
+
+template< bool Signed >
+struct operations< 8u, Signed > :
+    public msvc_x86_operations< 8u, Signed, operations< 8u, Signed > >
+{
+    typedef msvc_x86_operations< 8u, Signed, operations< 8u, Signed > > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(&storage, v));
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(&storage, v));
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type previous = expected;
+        storage_type old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(&storage, desired, previous));
+        expected = old_val;
+        return (previous == old_val);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND64(&storage, v));
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR64(&storage, v));
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        return static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR64(&storage, v));
+    }
+};
+
+#endif
+
+#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)
+
+template< bool Signed >
+struct msvc_dcas_x86_64
+{
+    typedef typename storage_traits< 16u >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true;
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 16u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 16u;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type value = const_cast< storage_type& >(storage);
+        while (!BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE128(&storage, v, &value)) {}
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT
+    {
+        storage_type value = storage_type();
+        BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE128(&storage, value, &value);
+        return value;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
+    {
+        return !!BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE128(&storage, desired, &expected);
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        return compare_exchange_strong(storage, expected, desired, success_order, failure_order);
+    }
+};
+
+template< bool Signed >
+struct operations< 16u, Signed > :
+    public cas_based_operations< cas_based_exchange< msvc_dcas_x86_64< Signed > > >
+{
+};
+
+#endif // defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)
+
+BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
+{
+    BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+    if (order == memory_order_seq_cst)
+        msvc_x86_operations_base::hardware_full_fence();
+    BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+}
+
+BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
+{
+    if (order != memory_order_relaxed)
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+}
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#if defined(BOOST_MSVC)
+#pragma warning(pop)
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_MSVC_X86_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/ops_windows.hpp b/ThirdParty/boost/atomic/detail/ops_windows.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5170a64c3fa6aa6a9eb7bfee4e343cee41e796aa
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/ops_windows.hpp
@@ -0,0 +1,218 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2012 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/ops_windows.hpp
+ *
+ * This header contains implementation of the \c operations template.
+ *
+ * This implementation is the most basic version for Windows. It should
+ * work for any non-MSVC-like compilers as long as there are Interlocked WinAPI
+ * functions available. This version is also used for WinCE.
+ *
+ * Notably, this implementation is not as efficient as other
+ * versions based on compiler intrinsics.
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_OPS_WINDOWS_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_OPS_WINDOWS_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/memory_order.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/interlocked.hpp>
+#include <boost/atomic/detail/storage_traits.hpp>
+#include <boost/atomic/detail/operations_fwd.hpp>
+#include <boost/atomic/detail/type_traits/make_signed.hpp>
+#include <boost/atomic/capabilities.hpp>
+#include <boost/atomic/detail/ops_msvc_common.hpp>
+#include <boost/atomic/detail/ops_extending_cas_based.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+struct windows_operations_base
+{
+    static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false;
+    static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
+
+    static BOOST_FORCEINLINE void hardware_full_fence() BOOST_NOEXCEPT
+    {
+        long tmp;
+        BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&tmp, 0);
+    }
+
+    static BOOST_FORCEINLINE void fence_before(memory_order) BOOST_NOEXCEPT
+    {
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+    }
+
+    static BOOST_FORCEINLINE void fence_after(memory_order) BOOST_NOEXCEPT
+    {
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+    }
+};
+
+template< std::size_t Size, bool Signed, typename Derived >
+struct windows_operations :
+    public windows_operations_base
+{
+    typedef typename storage_traits< Size >::type storage_type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = storage_traits< Size >::alignment;
+    static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
+
+    static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        Derived::exchange(storage, v, order);
+    }
+
+    static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return Derived::fetch_add(const_cast< storage_type volatile& >(storage), (storage_type)0, order);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        typedef typename boost::atomics::detail::make_signed< storage_type >::type signed_storage_type;
+        return Derived::fetch_add(storage, static_cast< storage_type >(-static_cast< signed_storage_type >(v)), order);
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_weak(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        return Derived::compare_exchange_strong(storage, expected, desired, success_order, failure_order);
+    }
+
+    static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        return !!Derived::exchange(storage, (storage_type)1, order);
+    }
+
+    static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
+    {
+        store(storage, (storage_type)0, order);
+    }
+};
+
+template< bool Signed >
+struct operations< 4u, Signed > :
+    public windows_operations< 4u, Signed, operations< 4u, Signed > >
+{
+    typedef windows_operations< 4u, Signed, operations< 4u, Signed > > base_type;
+    typedef typename base_type::storage_type storage_type;
+
+    static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(&storage, v));
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+        base_type::fence_before(order);
+        v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&storage, v));
+        base_type::fence_after(order);
+        return v;
+    }
+
+    static BOOST_FORCEINLINE bool compare_exchange_strong(
+        storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
+    {
+        storage_type previous = expected;
+        base_type::fence_before(success_order);
+        storage_type old_val = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&storage, desired, previous));
+        expected = old_val;
+        // The success and failure fences are the same anyway
+        base_type::fence_after(success_order);
+        return (previous == old_val);
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_INTERLOCKED_AND)
+        base_type::fence_before(order);
+        v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_AND(&storage, v));
+        base_type::fence_after(order);
+        return v;
+#else
+        storage_type res = storage;
+        while (!compare_exchange_strong(storage, res, res & v, order, memory_order_relaxed)) {}
+        return res;
+#endif
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_INTERLOCKED_OR)
+        base_type::fence_before(order);
+        v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_OR(&storage, v));
+        base_type::fence_after(order);
+        return v;
+#else
+        storage_type res = storage;
+        while (!compare_exchange_strong(storage, res, res | v, order, memory_order_relaxed)) {}
+        return res;
+#endif
+    }
+
+    static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
+    {
+#if defined(BOOST_ATOMIC_INTERLOCKED_XOR)
+        base_type::fence_before(order);
+        v = static_cast< storage_type >(BOOST_ATOMIC_INTERLOCKED_XOR(&storage, v));
+        base_type::fence_after(order);
+        return v;
+#else
+        storage_type res = storage;
+        while (!compare_exchange_strong(storage, res, res ^ v, order, memory_order_relaxed)) {}
+        return res;
+#endif
+    }
+};
+
+template< bool Signed >
+struct operations< 1u, Signed > :
+    public extending_cas_based_operations< operations< 4u, Signed >, 1u, Signed >
+{
+};
+
+template< bool Signed >
+struct operations< 2u, Signed > :
+    public extending_cas_based_operations< operations< 4u, Signed >, 2u, Signed >
+{
+};
+
+BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
+{
+    BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+    if (order == memory_order_seq_cst)
+        windows_operations_base::hardware_full_fence();
+    BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+}
+
+BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
+{
+    if (order != memory_order_relaxed)
+        BOOST_ATOMIC_DETAIL_COMPILER_BARRIER();
+}
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_OPS_WINDOWS_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/pause.hpp b/ThirdParty/boost/atomic/detail/pause.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..37aa5ca84eccbe2010a65407589a4364957d6dd8
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/pause.hpp
@@ -0,0 +1,43 @@
+/*
+ * 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)
+ *
+ * (C) Copyright 2013 Tim Blechmann
+ * (C) Copyright 2013 Andrey Semashev
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_PAUSE_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_PAUSE_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_IX86))
+extern "C" void _mm_pause(void);
+#if defined(BOOST_MSVC)
+#pragma intrinsic(_mm_pause)
+#endif
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+BOOST_FORCEINLINE void pause() BOOST_NOEXCEPT
+{
+#if defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_IX86))
+    _mm_pause();
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+    __asm__ __volatile__("pause;");
+#endif
+}
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_PAUSE_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/platform.hpp b/ThirdParty/boost/atomic/detail/platform.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..df4cc305ac1e109606bff9daa2f61acf45e69baf
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/platform.hpp
@@ -0,0 +1,163 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/platform.hpp
+ *
+ * This header defines macros for the target platform detection
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_PLATFORM_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_PLATFORM_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(__GNUC__) && defined(__arm__)
+
+// Newer gcc versions define __ARM_ARCH. Older ones don't, so we have to deduce ARM arch version from a bunch of version-specific macros.
+#if defined(__ARM_ARCH)
+#define BOOST_ATOMIC_DETAIL_ARM_ARCH __ARM_ARCH
+#elif defined(__ARM_ARCH_8A__)
+#define BOOST_ATOMIC_DETAIL_ARM_ARCH 8
+#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) ||\
+    defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) ||\
+    defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)
+#define BOOST_ATOMIC_DETAIL_ARM_ARCH 7
+#elif defined(__ARM_ARCH_6__)  || defined(__ARM_ARCH_6J__) ||\
+    defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) ||\
+    defined(__ARM_ARCH_6ZK__)
+#define BOOST_ATOMIC_DETAIL_ARM_ARCH 6
+#else
+// We are not interested in older versions - they don't support atomic ops
+#define BOOST_ATOMIC_DETAIL_ARM_ARCH 0
+#endif
+
+#endif // defined(__GNUC__) && defined(__arm__)
+
+#if !defined(BOOST_ATOMIC_FORCE_FALLBACK)
+
+// Determine the target platform.
+// The target platform describes the compiler and target architecture. It can be used by more generic backends, such as the ones
+// based on compiler intrinsics, to implement specialized operations in a non-generic way.
+
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+
+#define BOOST_ATOMIC_DETAIL_PLATFORM gcc_x86
+#define BOOST_ATOMIC_DETAIL_EXTRA_BACKEND gcc_x86
+
+#elif defined(__GNUC__) && (defined(__POWERPC__) || defined(__PPC__))
+
+#define BOOST_ATOMIC_DETAIL_PLATFORM gcc_ppc
+#define BOOST_ATOMIC_DETAIL_EXTRA_BACKEND gcc_ppc
+
+#elif defined(__GNUC__) && defined(__arm__) && (BOOST_ATOMIC_DETAIL_ARM_ARCH+0) >= 6
+
+#define BOOST_ATOMIC_DETAIL_PLATFORM gcc_arm
+#define BOOST_ATOMIC_DETAIL_EXTRA_BACKEND gcc_arm
+
+#elif (defined(__GNUC__) || defined(__SUNPRO_CC)) && (defined(__sparcv8plus) || defined(__sparc_v9__))
+
+#define BOOST_ATOMIC_DETAIL_PLATFORM gcc_sparc
+
+#elif defined(__GNUC__) && defined(__alpha__)
+
+#define BOOST_ATOMIC_DETAIL_PLATFORM gcc_alpha
+
+#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
+
+#define BOOST_ATOMIC_DETAIL_PLATFORM msvc_x86
+
+#elif defined(_MSC_VER) && _MSC_VER >= 1700 && (defined(_M_ARM) || defined(_M_ARM64))
+
+#define BOOST_ATOMIC_DETAIL_PLATFORM msvc_arm
+
+#endif
+
+// Compiler-based backends
+
+// IBM XL C++ Compiler has to be checked before GCC/Clang as it pretends to be one but does not support __atomic* intrinsics.
+// It does support GCC inline assembler though.
+#if !(defined(__ibmxl__) || defined(__IBMCPP__)) &&\
+    ((defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 407)) ||\
+        (defined(BOOST_CLANG) && ((__clang_major__ * 100 + __clang_minor__) >= 302))) &&\
+    (\
+        (__GCC_ATOMIC_BOOL_LOCK_FREE + 0) == 2 ||\
+        (__GCC_ATOMIC_CHAR_LOCK_FREE + 0) == 2 ||\
+        (__GCC_ATOMIC_SHORT_LOCK_FREE + 0) == 2 ||\
+        (__GCC_ATOMIC_INT_LOCK_FREE + 0) == 2 ||\
+        (__GCC_ATOMIC_LONG_LOCK_FREE + 0) == 2 ||\
+        (__GCC_ATOMIC_LLONG_LOCK_FREE + 0) == 2\
+    )
+
+#define BOOST_ATOMIC_DETAIL_BACKEND gcc_atomic
+
+#elif defined(BOOST_ATOMIC_DETAIL_PLATFORM)
+
+#define BOOST_ATOMIC_DETAIL_BACKEND BOOST_ATOMIC_DETAIL_PLATFORM
+
+#elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 401) &&\
+    (\
+        defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) ||\
+        defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) ||\
+        defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) ||\
+        defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) ||\
+        defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)\
+    )
+
+#define BOOST_ATOMIC_DETAIL_BACKEND gcc_sync
+
+#endif
+
+// OS-based backends
+
+#if !defined(BOOST_ATOMIC_DETAIL_BACKEND)
+
+#if defined(__linux__) && defined(__arm__)
+
+#define BOOST_ATOMIC_DETAIL_BACKEND linux_arm
+
+#elif defined(BOOST_WINDOWS) || defined(_WIN32_CE)
+
+#define BOOST_ATOMIC_DETAIL_BACKEND windows
+
+#endif
+
+#endif // !defined(BOOST_ATOMIC_DETAIL_BACKEND)
+
+#endif // !defined(BOOST_ATOMIC_FORCE_FALLBACK)
+
+#if !defined(BOOST_ATOMIC_DETAIL_BACKEND)
+#define BOOST_ATOMIC_DETAIL_BACKEND emulated
+#define BOOST_ATOMIC_EMULATED
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_FP_BACKEND)
+#define BOOST_ATOMIC_DETAIL_FP_BACKEND generic
+#define BOOST_ATOMIC_DETAIL_FP_BACKEND_GENERIC
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_EXTRA_BACKEND)
+#define BOOST_ATOMIC_DETAIL_EXTRA_BACKEND generic
+#define BOOST_ATOMIC_DETAIL_EXTRA_BACKEND_GENERIC
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_EXTRA_FP_BACKEND)
+#define BOOST_ATOMIC_DETAIL_EXTRA_FP_BACKEND generic
+#define BOOST_ATOMIC_DETAIL_EXTRA_FP_BACKEND_GENERIC
+#endif
+
+#define BOOST_ATOMIC_DETAIL_BACKEND_HEADER(prefix) <BOOST_JOIN(prefix, BOOST_ATOMIC_DETAIL_BACKEND).hpp>
+#define BOOST_ATOMIC_DETAIL_FP_BACKEND_HEADER(prefix) <BOOST_JOIN(prefix, BOOST_ATOMIC_DETAIL_FP_BACKEND).hpp>
+#define BOOST_ATOMIC_DETAIL_EXTRA_BACKEND_HEADER(prefix) <BOOST_JOIN(prefix, BOOST_ATOMIC_DETAIL_EXTRA_BACKEND).hpp>
+#define BOOST_ATOMIC_DETAIL_EXTRA_FP_BACKEND_HEADER(prefix) <BOOST_JOIN(prefix, BOOST_ATOMIC_DETAIL_EXTRA_FP_BACKEND).hpp>
+
+#endif // BOOST_ATOMIC_DETAIL_PLATFORM_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/storage_traits.hpp b/ThirdParty/boost/atomic/detail/storage_traits.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7160b20085027b50cb21d5c4a267ac134c390ad0
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/storage_traits.hpp
@@ -0,0 +1,193 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2009 Helge Bahmann
+ * Copyright (c) 2012 Tim Blechmann
+ * Copyright (c) 2013 - 2020 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/storage_traits.hpp
+ *
+ * This header defines underlying types used as storage
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_STORAGE_TRAITS_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_STORAGE_TRAITS_HPP_INCLUDED_
+
+#include <cstddef>
+#include <boost/cstdint.hpp>
+#include <boost/atomic/detail/config.hpp>
+#include <boost/atomic/detail/string_ops.hpp>
+#include <boost/atomic/detail/type_traits/alignment_of.hpp>
+#if defined(BOOST_ATOMIC_DETAIL_NO_CXX11_ALIGNAS)
+#include <boost/type_traits/type_with_alignment.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< typename T >
+BOOST_FORCEINLINE void non_atomic_load(T const volatile& from, T& to) BOOST_NOEXCEPT
+{
+    to = from;
+}
+
+template< std::size_t Size, std::size_t Alignment = 1u >
+struct BOOST_ATOMIC_DETAIL_MAY_ALIAS buffer_storage
+{
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_ALIGNAS)
+    alignas(Alignment) unsigned char data[Size];
+#else
+    union
+    {
+        unsigned char data[Size];
+        typename boost::type_with_alignment< Alignment >::type aligner;
+    };
+#endif
+
+    BOOST_FORCEINLINE bool operator! () const BOOST_NOEXCEPT
+    {
+        return (data[0] == 0u && BOOST_ATOMIC_DETAIL_MEMCMP(data, data + 1, Size - 1u) == 0);
+    }
+
+    BOOST_FORCEINLINE bool operator== (buffer_storage const& that) const BOOST_NOEXCEPT
+    {
+        return BOOST_ATOMIC_DETAIL_MEMCMP(data, that.data, Size) == 0;
+    }
+
+    BOOST_FORCEINLINE bool operator!= (buffer_storage const& that) const BOOST_NOEXCEPT
+    {
+        return BOOST_ATOMIC_DETAIL_MEMCMP(data, that.data, Size) != 0;
+    }
+};
+
+template< std::size_t Size, std::size_t Alignment >
+BOOST_FORCEINLINE void non_atomic_load(buffer_storage< Size, Alignment > const volatile& from, buffer_storage< Size, Alignment >& to) BOOST_NOEXCEPT
+{
+    BOOST_ATOMIC_DETAIL_MEMCPY(to.data, const_cast< unsigned char const* >(from.data), Size);
+}
+
+template< std::size_t Size >
+struct storage_traits
+{
+    typedef buffer_storage< Size, 1u > type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t native_alignment = 1u;
+
+    // By default, prefer the maximum supported alignment
+    static BOOST_CONSTEXPR_OR_CONST std::size_t alignment = 16u;
+};
+
+template< >
+struct storage_traits< 1u >
+{
+    typedef boost::uint8_t BOOST_ATOMIC_DETAIL_MAY_ALIAS type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t native_alignment = 1u;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t alignment = 1u;
+};
+
+template< >
+struct storage_traits< 2u >
+{
+    typedef boost::uint16_t BOOST_ATOMIC_DETAIL_MAY_ALIAS type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t native_alignment = atomics::detail::alignment_of< boost::uint16_t >::value;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t alignment = 2u;
+};
+
+template< >
+struct storage_traits< 4u >
+{
+    typedef boost::uint32_t BOOST_ATOMIC_DETAIL_MAY_ALIAS type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t native_alignment = atomics::detail::alignment_of< boost::uint32_t >::value;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t alignment = 4u;
+};
+
+template< >
+struct storage_traits< 8u >
+{
+    typedef boost::uint64_t BOOST_ATOMIC_DETAIL_MAY_ALIAS type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t native_alignment = atomics::detail::alignment_of< boost::uint64_t >::value;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t alignment = 8u;
+};
+
+#if defined(BOOST_HAS_INT128)
+
+template< >
+struct storage_traits< 16u >
+{
+    typedef boost::uint128_type BOOST_ATOMIC_DETAIL_MAY_ALIAS type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t native_alignment = atomics::detail::alignment_of< boost::uint128_type >::value;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t alignment = 16u;
+};
+
+#else
+
+#if (__cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)) &&\
+    (!defined(BOOST_GCC_VERSION) || BOOST_GCC_VERSION >= 40900)
+using std::max_align_t;
+#else
+
+#if defined(BOOST_MSVC)
+#pragma warning(push)
+// alignment is sensitive to packing
+#pragma warning(disable: 4121)
+#endif
+
+class max_align_helper;
+union max_align_t
+{
+    void* ptr;
+    void (*fun_ptr)();
+    int max_align_helper::*mem_ptr;
+    void (max_align_helper::*mem_fun_ptr)();
+    long long ll;
+    long double ld;
+#if defined(BOOST_HAS_INT128)
+    boost::int128_type i128;
+#endif
+#if defined(BOOST_HAS_FLOAT128)
+    boost::float128_type f128;
+#endif
+};
+
+#if defined(BOOST_MSVC)
+#pragma warning(pop)
+#endif
+
+#endif // __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
+
+template< >
+struct storage_traits< 16u >
+{
+    typedef buffer_storage< 16u, atomics::detail::alignment_of< atomics::detail::max_align_t >::value > type;
+
+    static BOOST_CONSTEXPR_OR_CONST std::size_t native_alignment = atomics::detail::alignment_of< atomics::detail::max_align_t >::value;
+    static BOOST_CONSTEXPR_OR_CONST std::size_t alignment = 16u;
+};
+
+#endif
+
+template< typename T >
+struct storage_size_of
+{
+    static BOOST_CONSTEXPR_OR_CONST std::size_t size = sizeof(T);
+    static BOOST_CONSTEXPR_OR_CONST std::size_t value = (size == 3u ? 4u : (size >= 5u && size <= 7u ? 8u : (size >= 9u && size <= 15u ? 16u : size)));
+};
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_STORAGE_TRAITS_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/string_ops.hpp b/ThirdParty/boost/atomic/detail/string_ops.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ce145b98f23f71ae4499a2802ad62c5fc3c8ee46
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/string_ops.hpp
@@ -0,0 +1,61 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/string_ops.hpp
+ *
+ * This header defines string operations for Boost.Atomic
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_STRING_OPS_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_STRING_OPS_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if defined(__has_builtin)
+#if __has_builtin(__builtin_memcpy)
+#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY
+#endif
+#if __has_builtin(__builtin_memcmp)
+#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP
+#endif
+#if __has_builtin(__builtin_memset)
+#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMSET
+#endif
+#elif defined(BOOST_GCC)
+#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY
+#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP
+#define BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMSET
+#endif
+
+#if defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY)
+#define BOOST_ATOMIC_DETAIL_MEMCPY __builtin_memcpy
+#else
+#define BOOST_ATOMIC_DETAIL_MEMCPY std::memcpy
+#endif
+
+#if defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP)
+#define BOOST_ATOMIC_DETAIL_MEMCMP __builtin_memcmp
+#else
+#define BOOST_ATOMIC_DETAIL_MEMCMP std::memcmp
+#endif
+
+#if defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMSET)
+#define BOOST_ATOMIC_DETAIL_MEMSET __builtin_memset
+#else
+#define BOOST_ATOMIC_DETAIL_MEMSET std::memset
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCPY) || !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMCMP) || !defined(BOOST_ATOMIC_DETAIL_HAS_BUILTIN_MEMSET)
+#include <cstring>
+#endif
+
+#endif // BOOST_ATOMIC_DETAIL_STRING_OPS_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/type_traits/alignment_of.hpp b/ThirdParty/boost/atomic/detail/type_traits/alignment_of.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..faef7d1df6efdca1c413474a35e3cf541bd16e73
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/type_traits/alignment_of.hpp
@@ -0,0 +1,51 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2020 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/type_traits/alignment_of.hpp
+ *
+ * This header defines \c alignment_of type trait
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_ALIGNMENT_OF_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_ALIGNMENT_OF_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+
+#if defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) ||\
+    (defined(BOOST_GCC) && (BOOST_GCC+0) < 80100) ||\
+    (defined(BOOST_CLANG) && !defined(__apple_build_version__) && (__clang_major__+0) < 8) ||\
+    (defined(BOOST_CLANG) && defined(__apple_build_version__) && (__clang_major__+0) < 9)
+// For some compilers std::alignment_of gives the wrong result for 64-bit types on 32-bit targets
+#define BOOST_ATOMIC_DETAIL_NO_CXX11_STD_ALIGNMENT_OF
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_STD_ALIGNMENT_OF)
+#include <type_traits>
+#else
+#include <boost/type_traits/alignment_of.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_STD_ALIGNMENT_OF)
+using std::alignment_of;
+#else
+using boost::alignment_of;
+#endif
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_ALIGNMENT_OF_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/type_traits/conditional.hpp b/ThirdParty/boost/atomic/detail/type_traits/conditional.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6b9e896729bcb16e4ff6198fb2e062eebed4a96e
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/type_traits/conditional.hpp
@@ -0,0 +1,42 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2017 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/type_traits/conditional.hpp
+ *
+ * This header defines \c conditional type trait
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_CONDITIONAL_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_CONDITIONAL_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS)
+#include <type_traits>
+#else
+#include <boost/type_traits/conditional.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS)
+using std::conditional;
+#else
+using boost::conditional;
+#endif
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_CONDITIONAL_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/type_traits/integral_constant.hpp b/ThirdParty/boost/atomic/detail/type_traits/integral_constant.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..eac86491e05ad29c9199ecd54dd36fa7843dd536
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/type_traits/integral_constant.hpp
@@ -0,0 +1,46 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2017 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/type_traits/integral_constant.hpp
+ *
+ * This header defines \c integral_constant wrapper
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_INTEGRAL_CONSTANT_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_INTEGRAL_CONSTANT_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS)
+#include <type_traits>
+#else
+#include <boost/type_traits/integral_constant.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS)
+using std::integral_constant;
+using std::true_type;
+using std::false_type;
+#else
+using boost::integral_constant;
+using boost::true_type;
+using boost::false_type;
+#endif
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_INTEGRAL_CONSTANT_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/type_traits/is_floating_point.hpp b/ThirdParty/boost/atomic/detail/type_traits/is_floating_point.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..46e2ab85eb594df0b087b1cc790e9bc712892bc6
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/type_traits/is_floating_point.hpp
@@ -0,0 +1,43 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/type_traits/is_floating_point.hpp
+ *
+ * This header defines \c is_floating_point type trait
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_FLOATING_POINT_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_FLOATING_POINT_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+// Some versions of libstdc++ don't consider __float128 a floating point type. Use Boost.TypeTraits because of that.
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_FLOAT128)
+#include <type_traits>
+#else
+#include <boost/type_traits/is_floating_point.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_FLOAT128)
+using std::is_floating_point;
+#else
+using boost::is_floating_point;
+#endif
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_FLOATING_POINT_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/type_traits/is_function.hpp b/ThirdParty/boost/atomic/detail/type_traits/is_function.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e7205356e45a41a77dfeafbdcfd06af322a6b3f1
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/type_traits/is_function.hpp
@@ -0,0 +1,42 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2017 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/type_traits/is_function.hpp
+ *
+ * This header defines \c is_function type trait
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_FUNCTION_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_FUNCTION_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS)
+#include <type_traits>
+#else
+#include <boost/type_traits/is_function.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS)
+using std::is_function;
+#else
+using boost::is_function;
+#endif
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_FUNCTION_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/type_traits/is_iec559.hpp b/ThirdParty/boost/atomic/detail/type_traits/is_iec559.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..299c4f0f4f8b82a042ca5abfc85fd1aabef64192
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/type_traits/is_iec559.hpp
@@ -0,0 +1,47 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/type_traits/is_iec559.hpp
+ *
+ * This header defines \c is_iec559 type trait
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_IEC559_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_IEC559_HPP_INCLUDED_
+
+#include <limits>
+#include <boost/atomic/detail/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+template< typename T >
+struct is_iec559
+{
+    static BOOST_CONSTEXPR_OR_CONST bool value = !!std::numeric_limits< T >::is_iec559;
+};
+
+#if defined(BOOST_HAS_FLOAT128)
+// libstdc++ does not specialize numeric_limits for __float128
+template< >
+struct is_iec559< boost::float128_type >
+{
+    static BOOST_CONSTEXPR_OR_CONST bool value = true;
+};
+#endif // defined(BOOST_HAS_FLOAT128)
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_IEC559_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/type_traits/is_integral.hpp b/ThirdParty/boost/atomic/detail/type_traits/is_integral.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ef3e2e347efb8f04c71ad6a0bf79f2a8bd1db663
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/type_traits/is_integral.hpp
@@ -0,0 +1,43 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2017 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/type_traits/is_integral.hpp
+ *
+ * This header defines \c is_integral type trait
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_INTEGRAL_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_INTEGRAL_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+// Some versions of libstdc++ don't consider __int128 an integral type. Use Boost.TypeTraits because of that.
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128)
+#include <type_traits>
+#else
+#include <boost/type_traits/is_integral.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128)
+using std::is_integral;
+#else
+using boost::is_integral;
+#endif
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_INTEGRAL_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/type_traits/is_signed.hpp b/ThirdParty/boost/atomic/detail/type_traits/is_signed.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2dc1df72678ba7999bcf3792b4c73d4c0236de1c
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/type_traits/is_signed.hpp
@@ -0,0 +1,43 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2017 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/type_traits/is_signed.hpp
+ *
+ * This header defines \c is_signed type trait
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_SIGNED_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_SIGNED_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+// Some versions of libstdc++ don't consider __int128 an integral type. Use Boost.TypeTraits because of that.
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128)
+#include <type_traits>
+#else
+#include <boost/type_traits/is_signed.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128)
+using std::is_signed;
+#else
+using boost::is_signed;
+#endif
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_SIGNED_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/type_traits/is_trivially_copyable.hpp b/ThirdParty/boost/atomic/detail/type_traits/is_trivially_copyable.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..732321202c943810344a6e51a9e5cfcf26f893ca
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/type_traits/is_trivially_copyable.hpp
@@ -0,0 +1,45 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/type_traits/is_trivially_copyable.hpp
+ *
+ * This header defines \c is_trivially_copyable type trait
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_TRIVIALLY_COPYABLE_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_TRIVIALLY_COPYABLE_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
+#include <type_traits>
+#else
+// For std::is_trivially_copyable we require a genuine support from the compiler.
+// Fallback to is_pod or a false negative result in Boost.TypeTraits is not acceptable
+// as this trait will be used in a static assert and may deny valid uses of boost::atomic/atomic_ref.
+#define BOOST_ATOMIC_DETAIL_NO_CXX11_IS_TRIVIALLY_COPYABLE
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_IS_TRIVIALLY_COPYABLE)
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+using std::is_trivially_copyable;
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_IS_TRIVIALLY_COPYABLE)
+
+#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_TRIVIALLY_COPYABLE_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp b/ThirdParty/boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5f88b88e428c72c4fd72c1727d47b809a8ef4570
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/type_traits/is_trivially_default_constructible.hpp
@@ -0,0 +1,46 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2018 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/type_traits/is_trivially_default_constructible.hpp
+ *
+ * This header defines \c is_trivially_default_constructible type trait
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
+#include <type_traits>
+#else
+#include <boost/type_traits/has_trivial_constructor.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
+using std::is_trivially_default_constructible;
+#elif !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
+template< typename T >
+using is_trivially_default_constructible = boost::has_trivial_constructor< T >;
+#else
+template< typename T >
+struct is_trivially_default_constructible : public boost::has_trivial_constructor< T > {};
+#endif
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/type_traits/make_signed.hpp b/ThirdParty/boost/atomic/detail/type_traits/make_signed.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..82f61b33c073c929ce3eee5901bbb0d8c7b478a8
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/type_traits/make_signed.hpp
@@ -0,0 +1,43 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2017 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/type_traits/make_signed.hpp
+ *
+ * This header defines \c make_signed type trait
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_MAKE_SIGNED_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_MAKE_SIGNED_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+// Some versions of libstdc++ don't consider __int128 an integral type. Use Boost.TypeTraits because of that.
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128)
+#include <type_traits>
+#else
+#include <boost/type_traits/make_signed.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128)
+using std::make_signed;
+#else
+using boost::make_signed;
+#endif
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_MAKE_SIGNED_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/detail/type_traits/make_unsigned.hpp b/ThirdParty/boost/atomic/detail/type_traits/make_unsigned.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..573a161694b1ae51c7494414c1bd49bb430e700c
--- /dev/null
+++ b/ThirdParty/boost/atomic/detail/type_traits/make_unsigned.hpp
@@ -0,0 +1,43 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2017 Andrey Semashev
+ */
+/*!
+ * \file   atomic/detail/type_traits/make_unsigned.hpp
+ *
+ * This header defines \c make_unsigned type trait
+ */
+
+#ifndef BOOST_ATOMIC_DETAIL_TYPE_TRAITS_MAKE_UNSIGNED_HPP_INCLUDED_
+#define BOOST_ATOMIC_DETAIL_TYPE_TRAITS_MAKE_UNSIGNED_HPP_INCLUDED_
+
+#include <boost/atomic/detail/config.hpp>
+// Some versions of libstdc++ don't consider __int128 an integral type. Use Boost.TypeTraits because of that.
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128)
+#include <type_traits>
+#else
+#include <boost/type_traits/make_unsigned.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+namespace atomics {
+namespace detail {
+
+#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_BASIC_HDR_TYPE_TRAITS) && !defined(BOOST_HAS_INT128)
+using std::make_unsigned;
+#else
+using boost::make_unsigned;
+#endif
+
+} // namespace detail
+} // namespace atomics
+} // namespace boost
+
+#endif // BOOST_ATOMIC_DETAIL_TYPE_TRAITS_MAKE_UNSIGNED_HPP_INCLUDED_
diff --git a/ThirdParty/boost/atomic/fences.hpp b/ThirdParty/boost/atomic/fences.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e91f6389bcf6a93119317b19cfa2effb688e7a10
--- /dev/null
+++ b/ThirdParty/boost/atomic/fences.hpp
@@ -0,0 +1,67 @@
+/*
+ * 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)
+ *
+ * Copyright (c) 2011 Helge Bahmann
+ * Copyright (c) 2013 Tim Blechmann
+ * Copyright (c) 2014 Andrey Semashev
+ */
+/*!
+ * \file   atomic/fences.hpp
+ *
+ * This header contains definition of \c atomic_thread_fence and \c atomic_signal_fence functions.
+ */
+
+#ifndef BOOST_ATOMIC_FENCES_HPP_INCLUDED_
+#define BOOST_ATOMIC_FENCES_HPP_INCLUDED_
+
+#include <boost/memory_order.hpp>
+#include <boost/atomic/capabilities.hpp>
+#include <boost/atomic/detail/operations.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+/*
+ * IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE,
+ *                      see comment for convert_memory_order_to_gcc in ops_gcc_atomic.hpp.
+ */
+
+namespace boost {
+
+namespace atomics {
+
+#if BOOST_ATOMIC_THREAD_FENCE > 0
+BOOST_FORCEINLINE void atomic_thread_fence(memory_order order) BOOST_NOEXCEPT
+{
+    atomics::detail::thread_fence(order);
+}
+#else
+BOOST_FORCEINLINE void atomic_thread_fence(memory_order) BOOST_NOEXCEPT
+{
+    atomics::detail::lock_pool::thread_fence();
+}
+#endif
+
+#if BOOST_ATOMIC_SIGNAL_FENCE > 0
+BOOST_FORCEINLINE void atomic_signal_fence(memory_order order) BOOST_NOEXCEPT
+{
+    atomics::detail::signal_fence(order);
+}
+#else
+BOOST_FORCEINLINE void atomic_signal_fence(memory_order) BOOST_NOEXCEPT
+{
+    atomics::detail::lock_pool::signal_fence();
+}
+#endif
+
+} // namespace atomics
+
+using atomics::atomic_thread_fence;
+using atomics::atomic_signal_fence;
+
+} // namespace boost
+
+#endif // BOOST_ATOMIC_FENCES_HPP_INCLUDED_
diff --git a/ThirdParty/boost/detail/lightweight_mutex.hpp b/ThirdParty/boost/detail/lightweight_mutex.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b7a7f6dd4ed6139f1c18bf8d33e5a7e7020669e0
--- /dev/null
+++ b/ThirdParty/boost/detail/lightweight_mutex.hpp
@@ -0,0 +1,22 @@
+#ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
+#define BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  boost/detail/lightweight_mutex.hpp - lightweight mutex
+//
+//  Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd.
+//
+//  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
+//
+
+#include <boost/smart_ptr/detail/lightweight_mutex.hpp>
+
+#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_MUTEX_HPP_INCLUDED
diff --git a/ThirdParty/boost/fusion/container/generation/ignore.hpp b/ThirdParty/boost/fusion/container/generation/ignore.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..781966322fc8565489ddb699c46c1eb4ebc24513
--- /dev/null
+++ b/ThirdParty/boost/fusion/container/generation/ignore.hpp
@@ -0,0 +1,35 @@
+/*=============================================================================
+    Copyright (c) 2001 Doug Gregor
+    Copyright (c) 1999-2003 Jaakko Jarvi
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_IGNORE_07192005_0329)
+#define FUSION_IGNORE_07192005_0329
+
+#include <boost/fusion/support/config.hpp>
+
+namespace boost { namespace fusion
+{
+    //  Swallows any assignment (by Doug Gregor)
+    namespace detail
+    {
+        struct swallow_assign
+        {
+            template<typename T>
+            BOOST_FUSION_CONSTEXPR_THIS BOOST_FUSION_GPU_ENABLED
+            swallow_assign const&
+            operator=(const T&) const
+            {
+                return *this;
+            }
+        };
+    }
+
+    //  "ignore" allows tuple positions to be ignored when using "tie".
+    BOOST_CONSTEXPR_OR_CONST detail::swallow_assign ignore = detail::swallow_assign();
+}}
+
+#endif
diff --git a/ThirdParty/boost/fusion/include/std_pair.hpp b/ThirdParty/boost/fusion/include/std_pair.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7a882a97ad21351db4c8651dbc6c00d23b60b5eb
--- /dev/null
+++ b/ThirdParty/boost/fusion/include/std_pair.hpp
@@ -0,0 +1,13 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_INCLUDE_STD_PAIR)
+#define FUSION_INCLUDE_STD_PAIR
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/adapted/std_pair.hpp>
+
+#endif
diff --git a/ThirdParty/boost/fusion/include/tuple.hpp b/ThirdParty/boost/fusion/include/tuple.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5d167f4f9d0fc131ebd8b3f8ce92556b4e824eaf
--- /dev/null
+++ b/ThirdParty/boost/fusion/include/tuple.hpp
@@ -0,0 +1,13 @@
+/*=============================================================================
+    Copyright (c) 2001-2007 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_INCLUDE_TUPLE)
+#define FUSION_INCLUDE_TUPLE
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/tuple.hpp>
+
+#endif
diff --git a/ThirdParty/boost/fusion/sequence/comparison.hpp b/ThirdParty/boost/fusion/sequence/comparison.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d319f9e07f5592876e333d48b694a763892eb925
--- /dev/null
+++ b/ThirdParty/boost/fusion/sequence/comparison.hpp
@@ -0,0 +1,18 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_SEQUENCE_COMPARISON_10022005_0615)
+#define FUSION_SEQUENCE_COMPARISON_10022005_0615
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/sequence/comparison/equal_to.hpp>
+#include <boost/fusion/sequence/comparison/greater.hpp>
+#include <boost/fusion/sequence/comparison/greater_equal.hpp>
+#include <boost/fusion/sequence/comparison/less.hpp>
+#include <boost/fusion/sequence/comparison/less_equal.hpp>
+#include <boost/fusion/sequence/comparison/not_equal_to.hpp>
+
+#endif
diff --git a/ThirdParty/boost/fusion/sequence/comparison/detail/greater.hpp b/ThirdParty/boost/fusion/sequence/comparison/detail/greater.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d762652935abde76e91193f7cdbf4a503ecb1124
--- /dev/null
+++ b/ThirdParty/boost/fusion/sequence/comparison/detail/greater.hpp
@@ -0,0 +1,55 @@
+/*=============================================================================
+    Copyright (c) 1999-2003 Jaakko Jarvi
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_GREATER_05052005_1142)
+#define FUSION_GREATER_05052005_1142
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/fusion/iterator/deref.hpp>
+#include <boost/fusion/iterator/next.hpp>
+#include <boost/fusion/iterator/equal_to.hpp>
+#include <boost/fusion/support/as_const.hpp>
+
+namespace boost { namespace fusion { namespace detail
+{
+    template <typename Seq1, typename Seq2>
+    struct sequence_greater
+    {
+        typedef typename result_of::end<Seq1>::type end1_type;
+        typedef typename result_of::end<Seq2>::type end2_type;
+
+        template <typename I1, typename I2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        static bool
+        call(I1 const&, I2 const&, mpl::true_)
+        {
+            return false;
+        }
+
+        template <typename I1, typename I2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        static bool
+        call(I1 const& a, I2 const& b, mpl::false_)
+        {
+            return extension::as_const(*a) > extension::as_const(*b) ||
+                (!(extension::as_const(*b) > extension::as_const(*a)) && 
+                 call(fusion::next(a), fusion::next(b)));
+        }
+
+        template <typename I1, typename I2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        static bool
+        call(I1 const& a, I2 const& b)
+        {
+            typename result_of::equal_to<I1, end1_type>::type eq;
+            return call(a, b, eq);
+        }
+    };
+}}}
+
+#endif
diff --git a/ThirdParty/boost/fusion/sequence/comparison/detail/greater_equal.hpp b/ThirdParty/boost/fusion/sequence/comparison/detail/greater_equal.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d15d88c40401a5e2960d9ccf50e9926ace883ef3
--- /dev/null
+++ b/ThirdParty/boost/fusion/sequence/comparison/detail/greater_equal.hpp
@@ -0,0 +1,55 @@
+/*=============================================================================
+    Copyright (c) 1999-2003 Jaakko Jarvi
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_GREATER_EQUAL_05052005_1142)
+#define FUSION_GREATER_EQUAL_05052005_1142
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/fusion/iterator/deref.hpp>
+#include <boost/fusion/iterator/next.hpp>
+#include <boost/fusion/iterator/equal_to.hpp>
+#include <boost/fusion/support/as_const.hpp>
+
+namespace boost { namespace fusion { namespace detail
+{
+    template <typename Seq1, typename Seq2>
+    struct sequence_greater_equal
+    {
+        typedef typename result_of::end<Seq1>::type end1_type;
+        typedef typename result_of::end<Seq2>::type end2_type;
+
+        template <typename I1, typename I2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        static bool
+        call(I1 const&, I2 const&, mpl::true_)
+        {
+            return true;
+        }
+
+        template <typename I1, typename I2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        static bool
+        call(I1 const& a, I2 const& b, mpl::false_)
+        {
+            return extension::as_const(*a) >= extension::as_const(*b)
+                && (!(extension::as_const(*b) >= extension::as_const(*a)) || 
+                    call(fusion::next(a), fusion::next(b)));
+        }
+
+        template <typename I1, typename I2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        static bool
+        call(I1 const& a, I2 const& b)
+        {
+            typename result_of::equal_to<I1, end1_type>::type eq;
+            return call(a, b, eq);
+        }
+    };
+}}}
+
+#endif
diff --git a/ThirdParty/boost/fusion/sequence/comparison/detail/less.hpp b/ThirdParty/boost/fusion/sequence/comparison/detail/less.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..04377d69603e9c7d0536c1ab8373480e1278da87
--- /dev/null
+++ b/ThirdParty/boost/fusion/sequence/comparison/detail/less.hpp
@@ -0,0 +1,55 @@
+/*=============================================================================
+    Copyright (c) 1999-2003 Jaakko Jarvi
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_LESS_05052005_1141)
+#define FUSION_LESS_05052005_1141
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/fusion/iterator/deref.hpp>
+#include <boost/fusion/iterator/next.hpp>
+#include <boost/fusion/iterator/equal_to.hpp>
+#include <boost/fusion/support/as_const.hpp>
+
+namespace boost { namespace fusion { namespace detail
+{
+    template <typename Seq1, typename Seq2>
+    struct sequence_less
+    {
+        typedef typename result_of::end<Seq1>::type end1_type;
+        typedef typename result_of::end<Seq2>::type end2_type;
+
+        template <typename I1, typename I2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        static bool
+        call(I1 const&, I2 const&, mpl::true_)
+        {
+            return false;
+        }
+
+        template <typename I1, typename I2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        static bool
+        call(I1 const& a, I2 const& b, mpl::false_)
+        {
+            return extension::as_const(*a) < extension::as_const(*b) ||
+                (!(extension::as_const(*b) < extension::as_const(*a)) && 
+                 call(fusion::next(a), fusion::next(b)));
+        }
+
+        template <typename I1, typename I2>
+        BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        static bool
+        call(I1 const& a, I2 const& b)
+        {
+            typename result_of::equal_to<I1, end1_type>::type eq;
+            return call(a, b, eq);
+        }
+    };
+}}}
+
+#endif
diff --git a/ThirdParty/boost/fusion/sequence/comparison/detail/less_equal.hpp b/ThirdParty/boost/fusion/sequence/comparison/detail/less_equal.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e61d33c4fa4d53980ca47df97801c5fab8d155ee
--- /dev/null
+++ b/ThirdParty/boost/fusion/sequence/comparison/detail/less_equal.hpp
@@ -0,0 +1,55 @@
+/*=============================================================================
+    Copyright (c) 1999-2003 Jaakko Jarvi
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_LESS_EQUAL_05052005_1141)
+#define FUSION_LESS_EQUAL_05052005_1141
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/fusion/iterator/deref.hpp>
+#include <boost/fusion/iterator/next.hpp>
+#include <boost/fusion/iterator/equal_to.hpp>
+#include <boost/fusion/support/as_const.hpp>
+
+namespace boost { namespace fusion { namespace detail
+{
+    template <typename Seq1, typename Seq2>
+    struct sequence_less_equal
+    {
+        typedef typename result_of::end<Seq1>::type end1_type;
+        typedef typename result_of::end<Seq2>::type end2_type;
+
+        template <typename I1, typename I2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        static bool
+        call(I1 const&, I2 const&, mpl::true_)
+        {
+            return true;
+        }
+
+        template <typename I1, typename I2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        static bool
+        call(I1 const& a, I2 const& b, mpl::false_)
+        {
+            return extension::as_const(*a) <= extension::as_const(*b)
+                && (!(extension::as_const(*b) <= extension::as_const(*a)) || 
+                    call(fusion::next(a), fusion::next(b)));
+        }
+
+        template <typename I1, typename I2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        static bool
+        call(I1 const& a, I2 const& b)
+        {
+            typename result_of::equal_to<I1, end1_type>::type eq;
+            return call(a, b, eq);
+        }
+    };
+}}}
+
+#endif
diff --git a/ThirdParty/boost/fusion/sequence/comparison/detail/not_equal_to.hpp b/ThirdParty/boost/fusion/sequence/comparison/detail/not_equal_to.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..323b2ac9d0929033d74f84404d8922d2f094a09d
--- /dev/null
+++ b/ThirdParty/boost/fusion/sequence/comparison/detail/not_equal_to.hpp
@@ -0,0 +1,66 @@
+/*=============================================================================
+    Copyright (c) 1999-2003 Jaakko Jarvi
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_NOT_EQUAL_TO_05052005_1141)
+#define FUSION_NOT_EQUAL_TO_05052005_1141
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/fusion/iterator/deref.hpp>
+#include <boost/fusion/iterator/next.hpp>
+#include <boost/fusion/iterator/equal_to.hpp>
+#include <boost/fusion/support/as_const.hpp>
+
+namespace boost { namespace fusion { namespace detail
+{
+    template <typename Seq1, typename Seq2, bool same_size>
+    struct sequence_not_equal_to
+    {
+        typedef typename result_of::end<Seq1>::type end1_type;
+        typedef typename result_of::end<Seq2>::type end2_type;
+
+        template <typename I1, typename I2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        static bool
+        call(I1 const&, I2 const&, mpl::true_)
+        {
+            return false;
+        }
+
+        template <typename I1, typename I2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        static bool
+        call(I1 const& a, I2 const& b, mpl::false_)
+        {
+            return extension::as_const(*a) != extension::as_const(*b)
+                || call(fusion::next(a), fusion::next(b));
+        }
+
+        template <typename I1, typename I2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        static bool
+        call(I1 const& a, I2 const& b)
+        {
+            typename result_of::equal_to<I1, end1_type>::type eq;
+            return call(a, b, eq);
+        }
+    };
+
+    template <typename Seq1, typename Seq2>
+    struct sequence_not_equal_to<Seq1, Seq2, false>
+    {
+        template <typename I1, typename I2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        static bool
+        call(I1 const& a, I2 const& b)
+        {
+            return true;
+        }
+    };
+}}}
+
+#endif
diff --git a/ThirdParty/boost/fusion/sequence/comparison/greater.hpp b/ThirdParty/boost/fusion/sequence/comparison/greater.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..fbbb7bfae2fd1c7ab82593f70baca594d90a8719
--- /dev/null
+++ b/ThirdParty/boost/fusion/sequence/comparison/greater.hpp
@@ -0,0 +1,55 @@
+/*=============================================================================
+    Copyright (c) 1999-2003 Jaakko Jarvi
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_GREATER_05052005_0432)
+#define FUSION_GREATER_05052005_0432
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/sequence/intrinsic/begin.hpp>
+#include <boost/fusion/sequence/intrinsic/end.hpp>
+#include <boost/fusion/sequence/intrinsic/size.hpp>
+#include <boost/fusion/sequence/comparison/enable_comparison.hpp>
+
+#if defined(FUSION_DIRECT_OPERATOR_USAGE)
+#include <boost/fusion/sequence/comparison/detail/greater.hpp>
+#else
+#include <boost/fusion/sequence/comparison/less.hpp>
+#endif
+
+namespace boost { namespace fusion
+{
+    template <typename Seq1, typename Seq2>
+    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+    inline bool
+    greater(Seq1 const& a, Seq2 const& b)
+    {
+#if defined(FUSION_DIRECT_OPERATOR_USAGE)
+        return detail::sequence_greater<Seq1 const, Seq2 const>::
+            call(fusion::begin(a), fusion::begin(b));
+#else
+        return (b < a);
+#endif
+    }
+
+    namespace operators
+    {
+        template <typename Seq1, typename Seq2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        inline typename
+            boost::enable_if<
+                traits::enable_comparison<Seq1, Seq2>
+              , bool
+            >::type
+        operator>(Seq1 const& a, Seq2 const& b)
+        {
+            return fusion::greater(a, b);
+        }
+    }
+    using operators::operator>;
+}}
+
+#endif
diff --git a/ThirdParty/boost/fusion/sequence/comparison/greater_equal.hpp b/ThirdParty/boost/fusion/sequence/comparison/greater_equal.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7b91a8886b9e8a0f0e09fc082d1bf6e06ae2fcad
--- /dev/null
+++ b/ThirdParty/boost/fusion/sequence/comparison/greater_equal.hpp
@@ -0,0 +1,55 @@
+/*=============================================================================
+    Copyright (c) 1999-2003 Jaakko Jarvi
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_GREATER_EQUAL_05052005_0432)
+#define FUSION_GREATER_EQUAL_05052005_0432
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/sequence/intrinsic/begin.hpp>
+#include <boost/fusion/sequence/intrinsic/end.hpp>
+#include <boost/fusion/sequence/intrinsic/size.hpp>
+#include <boost/fusion/sequence/comparison/enable_comparison.hpp>
+
+#if defined(FUSION_DIRECT_OPERATOR_USAGE)
+#include <boost/fusion/sequence/comparison/detail/greater_equal.hpp>
+#else
+#include <boost/fusion/sequence/comparison/less.hpp>
+#endif
+
+namespace boost { namespace fusion
+{
+    template <typename Seq1, typename Seq2>
+    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+    inline bool
+    greater_equal(Seq1 const& a, Seq2 const& b)
+    {
+#if defined(FUSION_DIRECT_OPERATOR_USAGE)
+        return detail::sequence_greater_equal<Seq1 const, Seq2 const>::
+            call(fusion::begin(a), fusion::begin(b));
+#else
+        return !(a < b);
+#endif
+    }
+
+    namespace operators
+    {
+        template <typename Seq1, typename Seq2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        inline typename
+            boost::enable_if<
+                traits::enable_comparison<Seq1, Seq2>
+              , bool
+            >::type
+        operator>=(Seq1 const& a, Seq2 const& b)
+        {
+            return fusion::greater_equal(a, b);
+        }
+    }
+    using operators::operator>=;
+}}
+
+#endif
diff --git a/ThirdParty/boost/fusion/sequence/comparison/less.hpp b/ThirdParty/boost/fusion/sequence/comparison/less.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b056552a9ea70fc6698e08ffe807503afc9c71a7
--- /dev/null
+++ b/ThirdParty/boost/fusion/sequence/comparison/less.hpp
@@ -0,0 +1,46 @@
+/*=============================================================================
+    Copyright (c) 1999-2003 Jaakko Jarvi
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_LESS_05052005_0432)
+#define FUSION_LESS_05052005_0432
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/sequence/intrinsic/begin.hpp>
+#include <boost/fusion/sequence/intrinsic/end.hpp>
+#include <boost/fusion/sequence/intrinsic/size.hpp>
+#include <boost/fusion/sequence/comparison/detail/less.hpp>
+#include <boost/fusion/sequence/comparison/enable_comparison.hpp>
+
+namespace boost { namespace fusion
+{
+    template <typename Seq1, typename Seq2>
+    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+    inline bool
+    less(Seq1 const& a, Seq2 const& b)
+    {
+        return detail::sequence_less<Seq1 const, Seq2 const>::
+            call(fusion::begin(a), fusion::begin(b));
+    }
+
+    namespace operators
+    {
+        template <typename Seq1, typename Seq2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        inline typename
+            boost::enable_if<
+                traits::enable_comparison<Seq1, Seq2>
+              , bool
+            >::type
+        operator<(Seq1 const& a, Seq2 const& b)
+        {
+            return fusion::less(a, b);
+        }
+    }
+    using operators::operator<;
+}}
+
+#endif
diff --git a/ThirdParty/boost/fusion/sequence/comparison/less_equal.hpp b/ThirdParty/boost/fusion/sequence/comparison/less_equal.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c5dfa8d5c7420c9d6b0677b5812d8812f7d3daca
--- /dev/null
+++ b/ThirdParty/boost/fusion/sequence/comparison/less_equal.hpp
@@ -0,0 +1,55 @@
+/*=============================================================================
+    Copyright (c) 1999-2003 Jaakko Jarvi
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_LESS_EQUAL_05052005_0432)
+#define FUSION_LESS_EQUAL_05052005_0432
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/sequence/intrinsic/begin.hpp>
+#include <boost/fusion/sequence/intrinsic/end.hpp>
+#include <boost/fusion/sequence/intrinsic/size.hpp>
+#include <boost/fusion/sequence/comparison/enable_comparison.hpp>
+
+#if defined(FUSION_DIRECT_OPERATOR_USAGE)
+#include <boost/fusion/sequence/comparison/detail/less_equal.hpp>
+#else
+#include <boost/fusion/sequence/comparison/less.hpp>
+#endif
+
+namespace boost { namespace fusion
+{
+    template <typename Seq1, typename Seq2>
+    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+    inline bool
+    less_equal(Seq1 const& a, Seq2 const& b)
+    {
+#if defined(FUSION_DIRECT_OPERATOR_USAGE)
+        return detail::sequence_less_equal<Seq1 const, Seq2 const>::
+            call(fusion::begin(a), fusion::begin(b));
+#else
+        return !(b < a);
+#endif
+    }
+
+    namespace operators
+    {
+        template <typename Seq1, typename Seq2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        inline typename
+            boost::enable_if<
+                traits::enable_comparison<Seq1, Seq2>
+              , bool
+            >::type
+        operator<=(Seq1 const& a, Seq2 const& b)
+        {
+            return fusion::less_equal(a, b);
+        }
+    }
+    using operators::operator<=;
+}}
+
+#endif
diff --git a/ThirdParty/boost/fusion/sequence/comparison/not_equal_to.hpp b/ThirdParty/boost/fusion/sequence/comparison/not_equal_to.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..fc2fef3343f7bd5ac746c0d96455a0c986c9ff5d
--- /dev/null
+++ b/ThirdParty/boost/fusion/sequence/comparison/not_equal_to.hpp
@@ -0,0 +1,58 @@
+/*=============================================================================
+    Copyright (c) 1999-2003 Jaakko Jarvi
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_NOT_EQUAL_TO_05052005_0431)
+#define FUSION_NOT_EQUAL_TO_05052005_0431
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/sequence/intrinsic/begin.hpp>
+#include <boost/fusion/sequence/intrinsic/end.hpp>
+#include <boost/fusion/sequence/intrinsic/size.hpp>
+#include <boost/fusion/sequence/comparison/enable_comparison.hpp>
+
+#if defined(FUSION_DIRECT_OPERATOR_USAGE)
+#include <boost/fusion/sequence/comparison/detail/not_equal_to.hpp>
+#else
+#include <boost/fusion/sequence/comparison/equal_to.hpp>
+#endif
+
+namespace boost { namespace fusion
+{
+    template <typename Seq1, typename Seq2>
+    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+    inline bool
+    not_equal_to(Seq1 const& a, Seq2 const& b)
+    {
+#if defined(FUSION_DIRECT_OPERATOR_USAGE)
+        return result_of::size<Seq1>::value != result_of::size<Seq2>::value
+            || detail::sequence_not_equal_to<
+            Seq1 const, Seq2 const
+            , result_of::size<Seq1>::value == result_of::size<Seq2>::value>::
+            call(fusion::begin(a), fusion::begin(b));
+#else
+        return !(a == b);
+#endif
+    }
+
+    namespace operators
+    {
+        template <typename Seq1, typename Seq2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        inline typename
+            boost::enable_if<
+                traits::enable_equality<Seq1, Seq2>
+              , bool
+            >::type
+        operator!=(Seq1 const& a, Seq2 const& b)
+        {
+            return fusion::not_equal_to(a, b);
+        }
+    }
+    using operators::operator!=;
+}}
+
+#endif
diff --git a/ThirdParty/boost/fusion/sequence/io.hpp b/ThirdParty/boost/fusion/sequence/io.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b0baf426c5fe4a119b1760e5f1c37ee7da1ffbeb
--- /dev/null
+++ b/ThirdParty/boost/fusion/sequence/io.hpp
@@ -0,0 +1,14 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_SEQUENCE_IO_10032005_0836)
+#define FUSION_SEQUENCE_IO_10032005_0836
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/sequence/io/in.hpp>
+#include <boost/fusion/sequence/io/out.hpp>
+
+#endif
diff --git a/ThirdParty/boost/fusion/sequence/io/detail/in.hpp b/ThirdParty/boost/fusion/sequence/io/detail/in.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d0a8dc4964a426e0dfcab30743edf0aa84ad1239
--- /dev/null
+++ b/ThirdParty/boost/fusion/sequence/io/detail/in.hpp
@@ -0,0 +1,86 @@
+/*=============================================================================
+    Copyright (c) 1999-2003 Jaakko Jarvi
+    Copyright (c) 1999-2003 Jeremiah Willcock
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_IN_05052005_0121)
+#define FUSION_IN_05052005_0121
+
+#include <boost/fusion/support/config.hpp>
+#include <istream>
+#include <boost/fusion/sequence/io/detail/manip.hpp>
+
+#include <boost/mpl/bool.hpp>
+#include <boost/fusion/sequence/intrinsic/begin.hpp>
+#include <boost/fusion/sequence/intrinsic/end.hpp>
+#include <boost/fusion/iterator/deref.hpp>
+#include <boost/fusion/iterator/next.hpp>
+#include <boost/fusion/iterator/equal_to.hpp>
+
+namespace boost { namespace fusion { namespace detail
+{
+    template <typename Tag>
+    struct delimiter_in
+    {
+        // read a delimiter
+        template <typename IS>
+        static void
+        read(IS& is, char const* delim, mpl::false_ = mpl::false_())
+        {
+            detail::string_ios_manip<Tag, IS> manip(is);
+            manip.read(delim);
+        }
+
+        template <typename IS>
+        static void
+        read(IS&, char const*, mpl::true_)
+        {
+        }
+    };
+
+    struct read_sequence_loop
+    {
+        template <typename IS, typename First, typename Last>
+        static void
+        call(IS&, First const&, Last const&, mpl::true_)
+        {
+        }
+
+        template <typename IS, typename First, typename Last>
+        static void
+        call(IS& is, First const& first, Last const& last, mpl::false_)
+        {
+            result_of::equal_to<
+                typename result_of::next<First>::type
+              , Last
+            >
+            is_last;
+
+            is >> *first;
+            delimiter_in<tuple_delimiter_tag>::read(is, " ", is_last);
+            call(is, fusion::next(first), last, is_last);
+        }
+
+        template <typename IS, typename First, typename Last>
+        static void
+        call(IS& is, First const& first, Last const& last)
+        {
+            result_of::equal_to<First, Last> eq;
+            call(is, first, last, eq);
+        }
+    };
+
+    template <typename IS, typename Sequence>
+    inline void
+    read_sequence(IS& is, Sequence& seq)
+    {
+        delimiter_in<tuple_open_tag>::read(is, "(");
+        read_sequence_loop::call(is, fusion::begin(seq), fusion::end(seq));
+        delimiter_in<tuple_close_tag>::read(is, ")");
+    }
+}}}
+
+#endif
diff --git a/ThirdParty/boost/fusion/sequence/io/detail/manip.hpp b/ThirdParty/boost/fusion/sequence/io/detail/manip.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..fc0d7d8204cdefa81b0eebf1d4a9adf09137b665
--- /dev/null
+++ b/ThirdParty/boost/fusion/sequence/io/detail/manip.hpp
@@ -0,0 +1,268 @@
+/*=============================================================================
+    Copyright (c) 1999-2003 Jeremiah Willcock
+    Copyright (c) 1999-2003 Jaakko Jarvi
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_MANIP_05052005_1200)
+#define FUSION_MANIP_05052005_1200
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/config.hpp>
+#include <string>
+#include <vector>
+#include <cctype>
+
+// Tuple I/O manipulators
+
+#define FUSION_GET_CHAR_TYPE(T) typename T::char_type
+#define FUSION_GET_TRAITS_TYPE(T) typename T::traits_type
+
+#define FUSION_STRING_OF_STREAM(Stream)                                         \
+    std::basic_string<                                                          \
+        FUSION_GET_CHAR_TYPE(Stream)                                            \
+      , FUSION_GET_TRAITS_TYPE(Stream)                                          \
+    >
+
+//$$$ these should be part of the public API$$$
+//$$$ rename tuple_open, tuple_close and tuple_delimiter to 
+//    open, close and delimeter and add these synonyms to the
+//    TR1 tuple module.
+
+namespace boost { namespace fusion
+{
+    namespace detail
+    {
+        template <typename Tag>
+        int get_xalloc_index(Tag* = 0)
+        {
+            // each Tag will have a unique index
+            static int index = std::ios::xalloc();
+            return index;
+        }
+
+        template <typename Stream, typename Tag, typename T>
+        struct stream_data
+        {
+            struct arena
+            {
+                ~arena()
+                {
+                    for (
+                        typename std::vector<T*>::iterator i = data.begin()
+                      ; i != data.end()
+                      ; ++i)
+                    {
+                        delete *i;
+                    }
+                }
+
+                std::vector<T*> data;
+            };
+
+            static void attach(Stream& stream, T const& data)
+            {
+                static arena ar; // our arena
+                ar.data.push_back(new T(data));
+                stream.pword(get_xalloc_index<Tag>()) = ar.data.back();
+            }
+
+            static T const* get(Stream& stream)
+            {
+                return (T const*)stream.pword(get_xalloc_index<Tag>());
+            }
+        };
+
+        template <typename Tag, typename Stream>
+        class string_ios_manip
+        {
+        public:
+
+            typedef FUSION_STRING_OF_STREAM(Stream) string_type;
+
+            typedef stream_data<Stream, Tag, string_type> stream_data_t;
+
+            string_ios_manip(Stream& str_)
+                : stream(str_)
+            {}
+
+            void
+            set(string_type const& s)
+            {
+                stream_data_t::attach(stream, s);
+            }
+
+            void
+            print(char const* default_) const
+            {
+                // print a delimiter
+                string_type const* p = stream_data_t::get(stream);
+                if (p)
+                    stream << *p;
+                else
+                    stream << default_;
+            }
+
+            void
+            read(char const* default_) const
+            {
+                // read a delimiter
+                string_type const* p = stream_data_t::get(stream);
+                std::ws(stream);
+
+                if (p)
+                {
+                    typedef typename string_type::const_iterator iterator;
+                    for (iterator i = p->begin(); i != p->end(); ++i)
+                        check_delim(*i);
+                }
+                else
+                {
+                    while (*default_)
+                        check_delim(*default_++);
+                }
+            }
+
+        private:
+
+            template <typename Char>
+            void
+            check_delim(Char c) const
+            {
+                using namespace std;
+                if (!isspace(c))
+                {
+                    if (stream.get() != c)
+                    {
+                        stream.unget();
+                        stream.setstate(std::ios::failbit);
+                    }
+                }
+            }
+
+            Stream& stream;
+
+            // silence MSVC warning C4512: assignment operator could not be generated
+            BOOST_DELETED_FUNCTION(string_ios_manip& operator= (string_ios_manip const&))
+        };
+
+    } // detail
+
+
+#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+
+#define STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(name)                            \
+    template <typename Char, typename Traits>                                   \
+    inline detail::name##_type<Char, Traits>                                    \
+    name(const std::basic_string<Char, Traits>& s)                              \
+    {                                                                           \
+        return detail::name##_type<Char, Traits>(s);                            \
+    }                                                                           \
+                                                                                \
+    inline detail::name##_type<char>                                            \
+    name(char const* s)                                                         \
+    {                                                                           \
+        return detail::name##_type<char>(std::basic_string<char>(s));           \
+    }                                                                           \
+                                                                                \
+    inline detail::name##_type<wchar_t>                                         \
+    name(wchar_t const* s)                                                      \
+    {                                                                           \
+        return detail::name##_type<wchar_t>(std::basic_string<wchar_t>(s));     \
+    }                                                                           \
+                                                                                \
+    inline detail::name##_type<char>                                            \
+    name(char c)                                                                \
+    {                                                                           \
+        return detail::name##_type<char>(std::basic_string<char>(1, c));        \
+    }                                                                           \
+                                                                                \
+    inline detail::name##_type<wchar_t>                                         \
+    name(wchar_t c)                                                             \
+    {                                                                           \
+        return detail::name##_type<wchar_t>(std::basic_string<wchar_t>(1, c));  \
+    }
+
+#else // defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+
+#define STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(name)                            \
+    template <typename Char, typename Traits>                                   \
+    inline detail::name##_type<Char, Traits>                                    \
+    name(const std::basic_string<Char, Traits>& s)                              \
+    {                                                                           \
+        return detail::name##_type<Char, Traits>(s);                            \
+    }                                                                           \
+                                                                                \
+    template <typename Char>                                                    \
+    inline detail::name##_type<Char>                                            \
+    name(Char s[])                                                              \
+    {                                                                           \
+        return detail::name##_type<Char>(std::basic_string<Char>(s));           \
+    }                                                                           \
+                                                                                \
+    template <typename Char>                                                    \
+    inline detail::name##_type<Char>                                            \
+    name(Char const s[])                                                        \
+    {                                                                           \
+        return detail::name##_type<Char>(std::basic_string<Char>(s));           \
+    }                                                                           \
+                                                                                \
+    template <typename Char>                                                    \
+    inline detail::name##_type<Char>                                            \
+    name(Char c)                                                                \
+    {                                                                           \
+        return detail::name##_type<Char>(std::basic_string<Char>(1, c));        \
+    }
+
+#endif
+
+#define STD_TUPLE_DEFINE_MANIPULATOR(name)                                      \
+    namespace detail                                                            \
+    {                                                                           \
+        struct name##_tag;                                                      \
+                                                                                \
+        template <typename Char, typename Traits = std::char_traits<Char> >     \
+        struct name##_type                                                      \
+        {                                                                       \
+            typedef std::basic_string<Char, Traits> string_type;                \
+            string_type data;                                                   \
+            name##_type(const string_type& d): data(d) {}                       \
+        };                                                                      \
+                                                                                \
+        template <typename Stream, typename Char, typename Traits>              \
+        Stream& operator>>(Stream& s, const name##_type<Char,Traits>& m)        \
+        {                                                                       \
+            string_ios_manip<name##_tag, Stream> manip(s);                      \
+            manip.set(m.data);                                                  \
+            return s;                                                           \
+        }                                                                       \
+                                                                                \
+        template <typename Stream, typename Char, typename Traits>              \
+        Stream& operator<<(Stream& s, const name##_type<Char,Traits>& m)        \
+        {                                                                       \
+            string_ios_manip<name##_tag, Stream> manip(s);                      \
+            manip.set(m.data);                                                  \
+            return s;                                                           \
+        }                                                                       \
+    }                                                                           \
+
+
+    STD_TUPLE_DEFINE_MANIPULATOR(tuple_open)
+    STD_TUPLE_DEFINE_MANIPULATOR(tuple_close)
+    STD_TUPLE_DEFINE_MANIPULATOR(tuple_delimiter)
+
+    STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_open)
+    STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_close)
+    STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS(tuple_delimiter)
+
+#undef STD_TUPLE_DEFINE_MANIPULATOR
+#undef STD_TUPLE_DEFINE_MANIPULATOR_FUNCTIONS
+#undef FUSION_STRING_OF_STREAM
+#undef FUSION_GET_CHAR_TYPE
+#undef FUSION_GET_TRAITS_TYPE
+
+}}
+
+#endif
diff --git a/ThirdParty/boost/fusion/sequence/io/detail/out.hpp b/ThirdParty/boost/fusion/sequence/io/detail/out.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7da87a53a4127bc00b3a7338ee13a6c1e304da38
--- /dev/null
+++ b/ThirdParty/boost/fusion/sequence/io/detail/out.hpp
@@ -0,0 +1,86 @@
+/*=============================================================================
+    Copyright (c) 1999-2003 Jaakko Jarvi
+    Copyright (c) 1999-2003 Jeremiah Willcock
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_OUT_05052005_0121)
+#define FUSION_OUT_05052005_0121
+
+#include <boost/fusion/support/config.hpp>
+#include <ostream>
+#include <boost/fusion/sequence/io/detail/manip.hpp>
+
+#include <boost/mpl/bool.hpp>
+#include <boost/fusion/sequence/intrinsic/begin.hpp>
+#include <boost/fusion/sequence/intrinsic/end.hpp>
+#include <boost/fusion/iterator/deref.hpp>
+#include <boost/fusion/iterator/next.hpp>
+#include <boost/fusion/iterator/equal_to.hpp>
+
+namespace boost { namespace fusion { namespace detail
+{
+    template <typename Tag>
+    struct delimiter_out
+    {
+        // print a delimiter
+        template <typename OS>
+        static void
+        print(OS& os, char const* delim, mpl::false_ = mpl::false_())
+        {
+            detail::string_ios_manip<Tag, OS> manip(os);
+            manip.print(delim);
+        }
+
+        template <typename OS>
+        static void
+        print(OS&, char const*, mpl::true_)
+        {
+        }
+    };
+
+    struct print_sequence_loop
+    {
+        template <typename OS, typename First, typename Last>
+        static void
+        call(OS&, First const&, Last const&, mpl::true_)
+        {
+        }
+
+        template <typename OS, typename First, typename Last>
+        static void
+        call(OS& os, First const& first, Last const& last, mpl::false_)
+        {
+            result_of::equal_to<
+                typename result_of::next<First>::type
+              , Last
+            >
+            is_last;
+
+            os << *first;
+            delimiter_out<tuple_delimiter_tag>::print(os, " ", is_last);
+            call(os, fusion::next(first), last, is_last);
+        }
+
+        template <typename OS, typename First, typename Last>
+        static void
+        call(OS& os, First const& first, Last const& last)
+        {
+            result_of::equal_to<First, Last> eq;
+            call(os, first, last, eq);
+        }
+    };
+
+    template <typename OS, typename Sequence>
+    inline void
+    print_sequence(OS& os, Sequence const& seq)
+    {
+        delimiter_out<tuple_open_tag>::print(os, "(");
+        print_sequence_loop::call(os, fusion::begin(seq), fusion::end(seq));
+        delimiter_out<tuple_close_tag>::print(os, ")");
+    }
+}}}
+
+#endif
diff --git a/ThirdParty/boost/fusion/sequence/io/in.hpp b/ThirdParty/boost/fusion/sequence/io/in.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..288c247331b54673967d888b5b767036f20c6a79
--- /dev/null
+++ b/ThirdParty/boost/fusion/sequence/io/in.hpp
@@ -0,0 +1,43 @@
+/*=============================================================================
+    Copyright (c) 1999-2003 Jaakko Jarvi
+    Copyright (c) 1999-2003 Jeremiah Willcock
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(BOOST_IN_05042005_0120)
+#define BOOST_IN_05042005_0120
+
+#include <boost/fusion/support/config.hpp>
+#include <istream>
+#include <boost/fusion/sequence/io/detail/in.hpp>
+#include <boost/fusion/support/is_sequence.hpp>
+
+namespace boost { namespace fusion
+{
+    template <typename Sequence>
+    inline std::istream&
+    in(std::istream& is, Sequence& seq)
+    {
+        detail::read_sequence(is, seq);
+        return is;
+    }
+
+    namespace operators
+    {
+        template <typename Sequence>
+        inline typename
+            boost::enable_if<
+               fusion::traits::is_sequence<Sequence>
+              , std::istream&
+            >::type
+        operator>>(std::istream& is, Sequence& seq)
+        {
+            return fusion::in(is, seq);
+        }
+    }
+    using operators::operator>>;
+}}
+
+#endif
diff --git a/ThirdParty/boost/fusion/sequence/io/out.hpp b/ThirdParty/boost/fusion/sequence/io/out.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5c4637d57b67490248504629ebb6661dbc72d54d
--- /dev/null
+++ b/ThirdParty/boost/fusion/sequence/io/out.hpp
@@ -0,0 +1,45 @@
+/*=============================================================================
+    Copyright (c) 1999-2003 Jaakko Jarvi
+    Copyright (c) 1999-2003 Jeremiah Willcock
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(BOOST_OUT_05042005_0120)
+#define BOOST_OUT_05042005_0120
+
+#include <boost/fusion/support/config.hpp>
+#include <ostream>
+#include <boost/fusion/sequence/io/detail/out.hpp>
+#include <boost/fusion/support/is_sequence.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/or.hpp>
+
+namespace boost { namespace fusion
+{
+    template <typename Sequence>
+    inline std::ostream&
+    out(std::ostream& os, Sequence& seq)
+    {
+        detail::print_sequence(os, seq);
+        return os;
+    }
+    
+    namespace operators
+    {
+        template <typename Sequence>
+        inline typename
+            boost::enable_if<
+               fusion::traits::is_sequence<Sequence>
+              , std::ostream&
+            >::type
+        operator<<(std::ostream& os, Sequence const& seq)
+        {
+            return fusion::out(os, seq);
+        }
+    }
+    using operators::operator<<;
+}}
+
+#endif
diff --git a/ThirdParty/boost/fusion/tuple.hpp b/ThirdParty/boost/fusion/tuple.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..49dac1d745a9131a458ab339463b2dacf97033ab
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple.hpp
@@ -0,0 +1,17 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_TUPLE_10032005_0806)
+#define FUSION_TUPLE_10032005_0806
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/tuple/tuple.hpp>
+#include <boost/fusion/tuple/make_tuple.hpp>
+#include <boost/fusion/tuple/tuple_tie.hpp>
+#include <boost/fusion/container/generation/ignore.hpp>
+
+#endif
+
diff --git a/ThirdParty/boost/fusion/tuple/detail/make_tuple.hpp b/ThirdParty/boost/fusion/tuple/detail/make_tuple.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f87ea5a2315385fe79fdb1aa6878cff54ee222f0
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/make_tuple.hpp
@@ -0,0 +1,86 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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_PP_IS_ITERATING
+#if !defined(FUSION_MAKE_TUPLE_10032005_0843)
+#define FUSION_MAKE_TUPLE_10032005_0843
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/fusion/tuple/detail/tuple.hpp>
+#include <boost/fusion/support/detail/as_fusion_element.hpp>
+
+namespace boost { namespace fusion
+{
+    BOOST_FUSION_GPU_ENABLED inline tuple<>
+    make_tuple()
+    {
+        return tuple<>();
+    }
+}}
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/tuple/detail/preprocessed/make_tuple.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/make_tuple" FUSION_MAX_VECTOR_SIZE_STR ".hpp")
+#endif
+
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+#define BOOST_FUSION_AS_FUSION_ELEMENT(z, n, data)                               \
+    typename detail::as_fusion_element<BOOST_PP_CAT(T, n)>::type
+
+#define BOOST_PP_FILENAME_1 <boost/fusion/tuple/detail/make_tuple.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
+#include BOOST_PP_ITERATE()
+
+#undef BOOST_FUSION_AS_FUSION_ELEMENT
+
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+#else // defined(BOOST_PP_IS_ITERATING)
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#define N BOOST_PP_ITERATION()
+
+    template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>
+    make_tuple(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& arg))
+    {
+        return tuple<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>(
+            BOOST_PP_ENUM_PARAMS(N, arg));
+    }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6abb033688932c4e083586f6963634a2d2e81930
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple.hpp
@@ -0,0 +1,21 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+#if FUSION_MAX_VECTOR_SIZE <= 10
+#include <boost/fusion/tuple/detail/preprocessed/make_tuple10.hpp>
+#elif FUSION_MAX_VECTOR_SIZE <= 20
+#include <boost/fusion/tuple/detail/preprocessed/make_tuple20.hpp>
+#elif FUSION_MAX_VECTOR_SIZE <= 30
+#include <boost/fusion/tuple/detail/preprocessed/make_tuple30.hpp>
+#elif FUSION_MAX_VECTOR_SIZE <= 40
+#include <boost/fusion/tuple/detail/preprocessed/make_tuple40.hpp>
+#elif FUSION_MAX_VECTOR_SIZE <= 50
+#include <boost/fusion/tuple/detail/preprocessed/make_tuple50.hpp>
+#else
+#error "FUSION_MAX_VECTOR_SIZE out of bounds for preprocessed headers"
+#endif
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple10.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple10.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f0ba114d6e8bc76901e0d2b5ebab7befff0182f1
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple10.hpp
@@ -0,0 +1,91 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    template <typename T0>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type>
+    make_tuple(T0 const& arg0)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type>(
+            arg0);
+    }
+    template <typename T0 , typename T1>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type>(
+            arg0 , arg1);
+    }
+    template <typename T0 , typename T1 , typename T2>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type>(
+            arg0 , arg1 , arg2);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type>(
+            arg0 , arg1 , arg2 , arg3);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9);
+    }
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple20.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple20.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..31ef304e2a9be6857ee14612dbe668dffa4df63f
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple20.hpp
@@ -0,0 +1,171 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    template <typename T0>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type>
+    make_tuple(T0 const& arg0)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type>(
+            arg0);
+    }
+    template <typename T0 , typename T1>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type>(
+            arg0 , arg1);
+    }
+    template <typename T0 , typename T1 , typename T2>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type>(
+            arg0 , arg1 , arg2);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type>(
+            arg0 , arg1 , arg2 , arg3);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19);
+    }
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple30.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple30.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..850829f3c7d99a3b48a5d3b0fa631bf74c1a7cd0
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple30.hpp
@@ -0,0 +1,251 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    template <typename T0>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type>
+    make_tuple(T0 const& arg0)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type>(
+            arg0);
+    }
+    template <typename T0 , typename T1>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type>(
+            arg0 , arg1);
+    }
+    template <typename T0 , typename T1 , typename T2>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type>(
+            arg0 , arg1 , arg2);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type>(
+            arg0 , arg1 , arg2 , arg3);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29);
+    }
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple40.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple40.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c85741b958804467f02f7f3b1d002ef90279beb3
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple40.hpp
@@ -0,0 +1,331 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    template <typename T0>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type>
+    make_tuple(T0 const& arg0)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type>(
+            arg0);
+    }
+    template <typename T0 , typename T1>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type>(
+            arg0 , arg1);
+    }
+    template <typename T0 , typename T1 , typename T2>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type>(
+            arg0 , arg1 , arg2);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type>(
+            arg0 , arg1 , arg2 , arg3);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36 , T37 const& arg37)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36 , T37 const& arg37 , T38 const& arg38)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36 , T37 const& arg37 , T38 const& arg38 , T39 const& arg39)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39);
+    }
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple50.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple50.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b4c99c51801b5f98f0ae8bba10b93d17ab0eefb0
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/make_tuple50.hpp
@@ -0,0 +1,411 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    template <typename T0>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type>
+    make_tuple(T0 const& arg0)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type>(
+            arg0);
+    }
+    template <typename T0 , typename T1>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type>(
+            arg0 , arg1);
+    }
+    template <typename T0 , typename T1 , typename T2>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type>(
+            arg0 , arg1 , arg2);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type>(
+            arg0 , arg1 , arg2 , arg3);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36 , T37 const& arg37)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36 , T37 const& arg37 , T38 const& arg38)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36 , T37 const& arg37 , T38 const& arg38 , T39 const& arg39)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36 , T37 const& arg37 , T38 const& arg38 , T39 const& arg39 , T40 const& arg40)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36 , T37 const& arg37 , T38 const& arg38 , T39 const& arg39 , T40 const& arg40 , T41 const& arg41)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41 , typename T42>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type , typename detail::as_fusion_element<T42>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36 , T37 const& arg37 , T38 const& arg38 , T39 const& arg39 , T40 const& arg40 , T41 const& arg41 , T42 const& arg42)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type , typename detail::as_fusion_element<T42>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41 , typename T42 , typename T43>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type , typename detail::as_fusion_element<T42>::type , typename detail::as_fusion_element<T43>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36 , T37 const& arg37 , T38 const& arg38 , T39 const& arg39 , T40 const& arg40 , T41 const& arg41 , T42 const& arg42 , T43 const& arg43)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type , typename detail::as_fusion_element<T42>::type , typename detail::as_fusion_element<T43>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41 , typename T42 , typename T43 , typename T44>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type , typename detail::as_fusion_element<T42>::type , typename detail::as_fusion_element<T43>::type , typename detail::as_fusion_element<T44>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36 , T37 const& arg37 , T38 const& arg38 , T39 const& arg39 , T40 const& arg40 , T41 const& arg41 , T42 const& arg42 , T43 const& arg43 , T44 const& arg44)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type , typename detail::as_fusion_element<T42>::type , typename detail::as_fusion_element<T43>::type , typename detail::as_fusion_element<T44>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41 , typename T42 , typename T43 , typename T44 , typename T45>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type , typename detail::as_fusion_element<T42>::type , typename detail::as_fusion_element<T43>::type , typename detail::as_fusion_element<T44>::type , typename detail::as_fusion_element<T45>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36 , T37 const& arg37 , T38 const& arg38 , T39 const& arg39 , T40 const& arg40 , T41 const& arg41 , T42 const& arg42 , T43 const& arg43 , T44 const& arg44 , T45 const& arg45)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type , typename detail::as_fusion_element<T42>::type , typename detail::as_fusion_element<T43>::type , typename detail::as_fusion_element<T44>::type , typename detail::as_fusion_element<T45>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44 , arg45);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41 , typename T42 , typename T43 , typename T44 , typename T45 , typename T46>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type , typename detail::as_fusion_element<T42>::type , typename detail::as_fusion_element<T43>::type , typename detail::as_fusion_element<T44>::type , typename detail::as_fusion_element<T45>::type , typename detail::as_fusion_element<T46>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36 , T37 const& arg37 , T38 const& arg38 , T39 const& arg39 , T40 const& arg40 , T41 const& arg41 , T42 const& arg42 , T43 const& arg43 , T44 const& arg44 , T45 const& arg45 , T46 const& arg46)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type , typename detail::as_fusion_element<T42>::type , typename detail::as_fusion_element<T43>::type , typename detail::as_fusion_element<T44>::type , typename detail::as_fusion_element<T45>::type , typename detail::as_fusion_element<T46>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44 , arg45 , arg46);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41 , typename T42 , typename T43 , typename T44 , typename T45 , typename T46 , typename T47>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type , typename detail::as_fusion_element<T42>::type , typename detail::as_fusion_element<T43>::type , typename detail::as_fusion_element<T44>::type , typename detail::as_fusion_element<T45>::type , typename detail::as_fusion_element<T46>::type , typename detail::as_fusion_element<T47>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36 , T37 const& arg37 , T38 const& arg38 , T39 const& arg39 , T40 const& arg40 , T41 const& arg41 , T42 const& arg42 , T43 const& arg43 , T44 const& arg44 , T45 const& arg45 , T46 const& arg46 , T47 const& arg47)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type , typename detail::as_fusion_element<T42>::type , typename detail::as_fusion_element<T43>::type , typename detail::as_fusion_element<T44>::type , typename detail::as_fusion_element<T45>::type , typename detail::as_fusion_element<T46>::type , typename detail::as_fusion_element<T47>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44 , arg45 , arg46 , arg47);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41 , typename T42 , typename T43 , typename T44 , typename T45 , typename T46 , typename T47 , typename T48>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type , typename detail::as_fusion_element<T42>::type , typename detail::as_fusion_element<T43>::type , typename detail::as_fusion_element<T44>::type , typename detail::as_fusion_element<T45>::type , typename detail::as_fusion_element<T46>::type , typename detail::as_fusion_element<T47>::type , typename detail::as_fusion_element<T48>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36 , T37 const& arg37 , T38 const& arg38 , T39 const& arg39 , T40 const& arg40 , T41 const& arg41 , T42 const& arg42 , T43 const& arg43 , T44 const& arg44 , T45 const& arg45 , T46 const& arg46 , T47 const& arg47 , T48 const& arg48)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type , typename detail::as_fusion_element<T42>::type , typename detail::as_fusion_element<T43>::type , typename detail::as_fusion_element<T44>::type , typename detail::as_fusion_element<T45>::type , typename detail::as_fusion_element<T46>::type , typename detail::as_fusion_element<T47>::type , typename detail::as_fusion_element<T48>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44 , arg45 , arg46 , arg47 , arg48);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41 , typename T42 , typename T43 , typename T44 , typename T45 , typename T46 , typename T47 , typename T48 , typename T49>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type , typename detail::as_fusion_element<T42>::type , typename detail::as_fusion_element<T43>::type , typename detail::as_fusion_element<T44>::type , typename detail::as_fusion_element<T45>::type , typename detail::as_fusion_element<T46>::type , typename detail::as_fusion_element<T47>::type , typename detail::as_fusion_element<T48>::type , typename detail::as_fusion_element<T49>::type>
+    make_tuple(T0 const& arg0 , T1 const& arg1 , T2 const& arg2 , T3 const& arg3 , T4 const& arg4 , T5 const& arg5 , T6 const& arg6 , T7 const& arg7 , T8 const& arg8 , T9 const& arg9 , T10 const& arg10 , T11 const& arg11 , T12 const& arg12 , T13 const& arg13 , T14 const& arg14 , T15 const& arg15 , T16 const& arg16 , T17 const& arg17 , T18 const& arg18 , T19 const& arg19 , T20 const& arg20 , T21 const& arg21 , T22 const& arg22 , T23 const& arg23 , T24 const& arg24 , T25 const& arg25 , T26 const& arg26 , T27 const& arg27 , T28 const& arg28 , T29 const& arg29 , T30 const& arg30 , T31 const& arg31 , T32 const& arg32 , T33 const& arg33 , T34 const& arg34 , T35 const& arg35 , T36 const& arg36 , T37 const& arg37 , T38 const& arg38 , T39 const& arg39 , T40 const& arg40 , T41 const& arg41 , T42 const& arg42 , T43 const& arg43 , T44 const& arg44 , T45 const& arg45 , T46 const& arg46 , T47 const& arg47 , T48 const& arg48 , T49 const& arg49)
+    {
+        return tuple<typename detail::as_fusion_element<T0>::type , typename detail::as_fusion_element<T1>::type , typename detail::as_fusion_element<T2>::type , typename detail::as_fusion_element<T3>::type , typename detail::as_fusion_element<T4>::type , typename detail::as_fusion_element<T5>::type , typename detail::as_fusion_element<T6>::type , typename detail::as_fusion_element<T7>::type , typename detail::as_fusion_element<T8>::type , typename detail::as_fusion_element<T9>::type , typename detail::as_fusion_element<T10>::type , typename detail::as_fusion_element<T11>::type , typename detail::as_fusion_element<T12>::type , typename detail::as_fusion_element<T13>::type , typename detail::as_fusion_element<T14>::type , typename detail::as_fusion_element<T15>::type , typename detail::as_fusion_element<T16>::type , typename detail::as_fusion_element<T17>::type , typename detail::as_fusion_element<T18>::type , typename detail::as_fusion_element<T19>::type , typename detail::as_fusion_element<T20>::type , typename detail::as_fusion_element<T21>::type , typename detail::as_fusion_element<T22>::type , typename detail::as_fusion_element<T23>::type , typename detail::as_fusion_element<T24>::type , typename detail::as_fusion_element<T25>::type , typename detail::as_fusion_element<T26>::type , typename detail::as_fusion_element<T27>::type , typename detail::as_fusion_element<T28>::type , typename detail::as_fusion_element<T29>::type , typename detail::as_fusion_element<T30>::type , typename detail::as_fusion_element<T31>::type , typename detail::as_fusion_element<T32>::type , typename detail::as_fusion_element<T33>::type , typename detail::as_fusion_element<T34>::type , typename detail::as_fusion_element<T35>::type , typename detail::as_fusion_element<T36>::type , typename detail::as_fusion_element<T37>::type , typename detail::as_fusion_element<T38>::type , typename detail::as_fusion_element<T39>::type , typename detail::as_fusion_element<T40>::type , typename detail::as_fusion_element<T41>::type , typename detail::as_fusion_element<T42>::type , typename detail::as_fusion_element<T43>::type , typename detail::as_fusion_element<T44>::type , typename detail::as_fusion_element<T45>::type , typename detail::as_fusion_element<T46>::type , typename detail::as_fusion_element<T47>::type , typename detail::as_fusion_element<T48>::type , typename detail::as_fusion_element<T49>::type>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44 , arg45 , arg46 , arg47 , arg48 , arg49);
+    }
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3fd0e18becf217a1e4e1229dd1d0aa1d2640fa9a
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple.hpp
@@ -0,0 +1,22 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+#if FUSION_MAX_VECTOR_SIZE <= 10
+#include <boost/fusion/tuple/detail/preprocessed/tuple10.hpp>
+#elif FUSION_MAX_VECTOR_SIZE <= 20
+#include <boost/fusion/tuple/detail/preprocessed/tuple20.hpp>
+#elif FUSION_MAX_VECTOR_SIZE <= 30
+#include <boost/fusion/tuple/detail/preprocessed/tuple30.hpp>
+#elif FUSION_MAX_VECTOR_SIZE <= 40
+#include <boost/fusion/tuple/detail/preprocessed/tuple40.hpp>
+#elif FUSION_MAX_VECTOR_SIZE <= 50
+#include <boost/fusion/tuple/detail/preprocessed/tuple50.hpp>
+#else
+#error "FUSION_MAX_VECTOR_SIZE out of bounds for preprocessed headers"
+#endif
+
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple10.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple10.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a24a29a12ec88362bf113dd385790842e402f18f
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple10.hpp
@@ -0,0 +1,209 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9>
+    struct tuple : vector<T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9>
+    {
+        typedef vector<
+            T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9>
+        base_type;
+        BOOST_FUSION_GPU_ENABLED tuple()
+            : base_type() {}
+        BOOST_FUSION_GPU_ENABLED tuple(tuple const& rhs)
+            : base_type(static_cast<base_type const&>(rhs)) {}
+        template <typename U1, typename U2>
+        BOOST_FUSION_GPU_ENABLED
+        tuple(std::pair<U1, U2> const& rhs)
+            : base_type(rhs) {}
+    BOOST_FUSION_GPU_ENABLED
+    explicit
+    tuple(typename detail::call_param<T0 >::type arg0)
+        : base_type(arg0) {}
+    template <typename U0>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1)
+        : base_type(arg0 , arg1) {}
+    template <typename U0 , typename U1>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2)
+        : base_type(arg0 , arg1 , arg2) {}
+    template <typename U0 , typename U1 , typename U2>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3)
+        : base_type(arg0 , arg1 , arg2 , arg3) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+        template <typename T>
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(T const& rhs)
+        {
+            base_type::operator=(rhs);
+            return *this;
+        }
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(tuple const& rhs)
+        {
+            base_type::operator=(static_cast<base_type const&>(rhs));
+            return *this;
+        }
+        template <typename U1, typename U2>
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(std::pair<U1, U2> const& rhs)
+        {
+            base_type::operator=(rhs);
+            return *this;
+        }
+    };
+    template <typename Tuple>
+    struct tuple_size : result_of::size<Tuple> {};
+    template <int N, typename Tuple>
+    struct tuple_element : result_of::value_at_c<Tuple, N> {};
+    template <int N, typename Tuple>
+    BOOST_FUSION_GPU_ENABLED
+    inline typename
+        lazy_disable_if<
+            is_const<Tuple>
+          , result_of::at_c<Tuple, N>
+        >::type
+    get(Tuple& tup)
+    {
+        return at_c<N>(tup);
+    }
+    template <int N, typename Tuple>
+    BOOST_FUSION_GPU_ENABLED
+    inline typename result_of::at_c<Tuple const, N>::type
+    get(Tuple const& tup)
+    {
+        return at_c<N>(tup);
+    }
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple10_fwd.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple10_fwd.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7ec319608b3765fa0aa487c0afccd94c9b0e67b4
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple10_fwd.hpp
@@ -0,0 +1,16 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    struct void_;
+    template <
+        typename T0 = void_ , typename T1 = void_ , typename T2 = void_ , typename T3 = void_ , typename T4 = void_ , typename T5 = void_ , typename T6 = void_ , typename T7 = void_ , typename T8 = void_ , typename T9 = void_
+    >
+    struct tuple;
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple20.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple20.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..73de49ffb866b263dc558c60a702996ed6752a90
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple20.hpp
@@ -0,0 +1,349 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19>
+    struct tuple : vector<T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19>
+    {
+        typedef vector<
+            T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19>
+        base_type;
+        BOOST_FUSION_GPU_ENABLED tuple()
+            : base_type() {}
+        BOOST_FUSION_GPU_ENABLED tuple(tuple const& rhs)
+            : base_type(static_cast<base_type const&>(rhs)) {}
+        template <typename U1, typename U2>
+        BOOST_FUSION_GPU_ENABLED
+        tuple(std::pair<U1, U2> const& rhs)
+            : base_type(rhs) {}
+    BOOST_FUSION_GPU_ENABLED
+    explicit
+    tuple(typename detail::call_param<T0 >::type arg0)
+        : base_type(arg0) {}
+    template <typename U0>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1)
+        : base_type(arg0 , arg1) {}
+    template <typename U0 , typename U1>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2)
+        : base_type(arg0 , arg1 , arg2) {}
+    template <typename U0 , typename U1 , typename U2>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3)
+        : base_type(arg0 , arg1 , arg2 , arg3) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+        template <typename T>
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(T const& rhs)
+        {
+            base_type::operator=(rhs);
+            return *this;
+        }
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(tuple const& rhs)
+        {
+            base_type::operator=(static_cast<base_type const&>(rhs));
+            return *this;
+        }
+        template <typename U1, typename U2>
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(std::pair<U1, U2> const& rhs)
+        {
+            base_type::operator=(rhs);
+            return *this;
+        }
+    };
+    template <typename Tuple>
+    struct tuple_size : result_of::size<Tuple> {};
+    template <int N, typename Tuple>
+    struct tuple_element : result_of::value_at_c<Tuple, N> {};
+    template <int N, typename Tuple>
+    BOOST_FUSION_GPU_ENABLED
+    inline typename
+        lazy_disable_if<
+            is_const<Tuple>
+          , result_of::at_c<Tuple, N>
+        >::type
+    get(Tuple& tup)
+    {
+        return at_c<N>(tup);
+    }
+    template <int N, typename Tuple>
+    BOOST_FUSION_GPU_ENABLED
+    inline typename result_of::at_c<Tuple const, N>::type
+    get(Tuple const& tup)
+    {
+        return at_c<N>(tup);
+    }
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple20_fwd.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple20_fwd.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3769f890201246403ad8cd800dfcb976ffdde606
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple20_fwd.hpp
@@ -0,0 +1,16 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    struct void_;
+    template <
+        typename T0 = void_ , typename T1 = void_ , typename T2 = void_ , typename T3 = void_ , typename T4 = void_ , typename T5 = void_ , typename T6 = void_ , typename T7 = void_ , typename T8 = void_ , typename T9 = void_ , typename T10 = void_ , typename T11 = void_ , typename T12 = void_ , typename T13 = void_ , typename T14 = void_ , typename T15 = void_ , typename T16 = void_ , typename T17 = void_ , typename T18 = void_ , typename T19 = void_
+    >
+    struct tuple;
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple30.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple30.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9db26a0c9a13f42bb9d21dd0d3305c8ab953f7cc
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple30.hpp
@@ -0,0 +1,489 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29>
+    struct tuple : vector<T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29>
+    {
+        typedef vector<
+            T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29>
+        base_type;
+        BOOST_FUSION_GPU_ENABLED tuple()
+            : base_type() {}
+        BOOST_FUSION_GPU_ENABLED tuple(tuple const& rhs)
+            : base_type(static_cast<base_type const&>(rhs)) {}
+        template <typename U1, typename U2>
+        BOOST_FUSION_GPU_ENABLED
+        tuple(std::pair<U1, U2> const& rhs)
+            : base_type(rhs) {}
+    BOOST_FUSION_GPU_ENABLED
+    explicit
+    tuple(typename detail::call_param<T0 >::type arg0)
+        : base_type(arg0) {}
+    template <typename U0>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1)
+        : base_type(arg0 , arg1) {}
+    template <typename U0 , typename U1>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2)
+        : base_type(arg0 , arg1 , arg2) {}
+    template <typename U0 , typename U1 , typename U2>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3)
+        : base_type(arg0 , arg1 , arg2 , arg3) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+        template <typename T>
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(T const& rhs)
+        {
+            base_type::operator=(rhs);
+            return *this;
+        }
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(tuple const& rhs)
+        {
+            base_type::operator=(static_cast<base_type const&>(rhs));
+            return *this;
+        }
+        template <typename U1, typename U2>
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(std::pair<U1, U2> const& rhs)
+        {
+            base_type::operator=(rhs);
+            return *this;
+        }
+    };
+    template <typename Tuple>
+    struct tuple_size : result_of::size<Tuple> {};
+    template <int N, typename Tuple>
+    struct tuple_element : result_of::value_at_c<Tuple, N> {};
+    template <int N, typename Tuple>
+    BOOST_FUSION_GPU_ENABLED
+    inline typename
+        lazy_disable_if<
+            is_const<Tuple>
+          , result_of::at_c<Tuple, N>
+        >::type
+    get(Tuple& tup)
+    {
+        return at_c<N>(tup);
+    }
+    template <int N, typename Tuple>
+    BOOST_FUSION_GPU_ENABLED
+    inline typename result_of::at_c<Tuple const, N>::type
+    get(Tuple const& tup)
+    {
+        return at_c<N>(tup);
+    }
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple30_fwd.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple30_fwd.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b9f3e017c32d32597a78330333b97b74a0b3e82b
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple30_fwd.hpp
@@ -0,0 +1,16 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    struct void_;
+    template <
+        typename T0 = void_ , typename T1 = void_ , typename T2 = void_ , typename T3 = void_ , typename T4 = void_ , typename T5 = void_ , typename T6 = void_ , typename T7 = void_ , typename T8 = void_ , typename T9 = void_ , typename T10 = void_ , typename T11 = void_ , typename T12 = void_ , typename T13 = void_ , typename T14 = void_ , typename T15 = void_ , typename T16 = void_ , typename T17 = void_ , typename T18 = void_ , typename T19 = void_ , typename T20 = void_ , typename T21 = void_ , typename T22 = void_ , typename T23 = void_ , typename T24 = void_ , typename T25 = void_ , typename T26 = void_ , typename T27 = void_ , typename T28 = void_ , typename T29 = void_
+    >
+    struct tuple;
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple40.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple40.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..44e0d2c1d514dcde54df9aa83123887551b6c326
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple40.hpp
@@ -0,0 +1,629 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39>
+    struct tuple : vector<T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39>
+    {
+        typedef vector<
+            T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39>
+        base_type;
+        BOOST_FUSION_GPU_ENABLED tuple()
+            : base_type() {}
+        BOOST_FUSION_GPU_ENABLED tuple(tuple const& rhs)
+            : base_type(static_cast<base_type const&>(rhs)) {}
+        template <typename U1, typename U2>
+        BOOST_FUSION_GPU_ENABLED
+        tuple(std::pair<U1, U2> const& rhs)
+            : base_type(rhs) {}
+    BOOST_FUSION_GPU_ENABLED
+    explicit
+    tuple(typename detail::call_param<T0 >::type arg0)
+        : base_type(arg0) {}
+    template <typename U0>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1)
+        : base_type(arg0 , arg1) {}
+    template <typename U0 , typename U1>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2)
+        : base_type(arg0 , arg1 , arg2) {}
+    template <typename U0 , typename U1 , typename U2>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3)
+        : base_type(arg0 , arg1 , arg2 , arg3) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36 , typename detail::call_param<T37 >::type arg37)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36 , typename detail::call_param<T37 >::type arg37 , typename detail::call_param<T38 >::type arg38)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36 , typename detail::call_param<T37 >::type arg37 , typename detail::call_param<T38 >::type arg38 , typename detail::call_param<T39 >::type arg39)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+        template <typename T>
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(T const& rhs)
+        {
+            base_type::operator=(rhs);
+            return *this;
+        }
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(tuple const& rhs)
+        {
+            base_type::operator=(static_cast<base_type const&>(rhs));
+            return *this;
+        }
+        template <typename U1, typename U2>
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(std::pair<U1, U2> const& rhs)
+        {
+            base_type::operator=(rhs);
+            return *this;
+        }
+    };
+    template <typename Tuple>
+    struct tuple_size : result_of::size<Tuple> {};
+    template <int N, typename Tuple>
+    struct tuple_element : result_of::value_at_c<Tuple, N> {};
+    template <int N, typename Tuple>
+    BOOST_FUSION_GPU_ENABLED
+    inline typename
+        lazy_disable_if<
+            is_const<Tuple>
+          , result_of::at_c<Tuple, N>
+        >::type
+    get(Tuple& tup)
+    {
+        return at_c<N>(tup);
+    }
+    template <int N, typename Tuple>
+    BOOST_FUSION_GPU_ENABLED
+    inline typename result_of::at_c<Tuple const, N>::type
+    get(Tuple const& tup)
+    {
+        return at_c<N>(tup);
+    }
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple40_fwd.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple40_fwd.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..200bf5db500585f651034da5af883be7c3b25fcc
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple40_fwd.hpp
@@ -0,0 +1,16 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    struct void_;
+    template <
+        typename T0 = void_ , typename T1 = void_ , typename T2 = void_ , typename T3 = void_ , typename T4 = void_ , typename T5 = void_ , typename T6 = void_ , typename T7 = void_ , typename T8 = void_ , typename T9 = void_ , typename T10 = void_ , typename T11 = void_ , typename T12 = void_ , typename T13 = void_ , typename T14 = void_ , typename T15 = void_ , typename T16 = void_ , typename T17 = void_ , typename T18 = void_ , typename T19 = void_ , typename T20 = void_ , typename T21 = void_ , typename T22 = void_ , typename T23 = void_ , typename T24 = void_ , typename T25 = void_ , typename T26 = void_ , typename T27 = void_ , typename T28 = void_ , typename T29 = void_ , typename T30 = void_ , typename T31 = void_ , typename T32 = void_ , typename T33 = void_ , typename T34 = void_ , typename T35 = void_ , typename T36 = void_ , typename T37 = void_ , typename T38 = void_ , typename T39 = void_
+    >
+    struct tuple;
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple50.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple50.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..db157b65491ec7f8741f7575a0825332c3488c9b
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple50.hpp
@@ -0,0 +1,769 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41 , typename T42 , typename T43 , typename T44 , typename T45 , typename T46 , typename T47 , typename T48 , typename T49>
+    struct tuple : vector<T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 , T46 , T47 , T48 , T49>
+    {
+        typedef vector<
+            T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 , T25 , T26 , T27 , T28 , T29 , T30 , T31 , T32 , T33 , T34 , T35 , T36 , T37 , T38 , T39 , T40 , T41 , T42 , T43 , T44 , T45 , T46 , T47 , T48 , T49>
+        base_type;
+        BOOST_FUSION_GPU_ENABLED tuple()
+            : base_type() {}
+        BOOST_FUSION_GPU_ENABLED tuple(tuple const& rhs)
+            : base_type(static_cast<base_type const&>(rhs)) {}
+        template <typename U1, typename U2>
+        BOOST_FUSION_GPU_ENABLED
+        tuple(std::pair<U1, U2> const& rhs)
+            : base_type(rhs) {}
+    BOOST_FUSION_GPU_ENABLED
+    explicit
+    tuple(typename detail::call_param<T0 >::type arg0)
+        : base_type(arg0) {}
+    template <typename U0>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1)
+        : base_type(arg0 , arg1) {}
+    template <typename U0 , typename U1>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2)
+        : base_type(arg0 , arg1 , arg2) {}
+    template <typename U0 , typename U1 , typename U2>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3)
+        : base_type(arg0 , arg1 , arg2 , arg3) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36 , typename detail::call_param<T37 >::type arg37)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36 , typename detail::call_param<T37 >::type arg37 , typename detail::call_param<T38 >::type arg38)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36 , typename detail::call_param<T37 >::type arg37 , typename detail::call_param<T38 >::type arg38 , typename detail::call_param<T39 >::type arg39)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36 , typename detail::call_param<T37 >::type arg37 , typename detail::call_param<T38 >::type arg38 , typename detail::call_param<T39 >::type arg39 , typename detail::call_param<T40 >::type arg40)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36 , typename detail::call_param<T37 >::type arg37 , typename detail::call_param<T38 >::type arg38 , typename detail::call_param<T39 >::type arg39 , typename detail::call_param<T40 >::type arg40 , typename detail::call_param<T41 >::type arg41)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36 , typename detail::call_param<T37 >::type arg37 , typename detail::call_param<T38 >::type arg38 , typename detail::call_param<T39 >::type arg39 , typename detail::call_param<T40 >::type arg40 , typename detail::call_param<T41 >::type arg41 , typename detail::call_param<T42 >::type arg42)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36 , typename detail::call_param<T37 >::type arg37 , typename detail::call_param<T38 >::type arg38 , typename detail::call_param<T39 >::type arg39 , typename detail::call_param<T40 >::type arg40 , typename detail::call_param<T41 >::type arg41 , typename detail::call_param<T42 >::type arg42 , typename detail::call_param<T43 >::type arg43)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42 , typename U43>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42 , typename U43>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36 , typename detail::call_param<T37 >::type arg37 , typename detail::call_param<T38 >::type arg38 , typename detail::call_param<T39 >::type arg39 , typename detail::call_param<T40 >::type arg40 , typename detail::call_param<T41 >::type arg41 , typename detail::call_param<T42 >::type arg42 , typename detail::call_param<T43 >::type arg43 , typename detail::call_param<T44 >::type arg44)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42 , typename U43 , typename U44>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43 , U44> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42 , typename U43 , typename U44>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43 , U44> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36 , typename detail::call_param<T37 >::type arg37 , typename detail::call_param<T38 >::type arg38 , typename detail::call_param<T39 >::type arg39 , typename detail::call_param<T40 >::type arg40 , typename detail::call_param<T41 >::type arg41 , typename detail::call_param<T42 >::type arg42 , typename detail::call_param<T43 >::type arg43 , typename detail::call_param<T44 >::type arg44 , typename detail::call_param<T45 >::type arg45)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44 , arg45) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42 , typename U43 , typename U44 , typename U45>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43 , U44 , U45> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42 , typename U43 , typename U44 , typename U45>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43 , U44 , U45> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36 , typename detail::call_param<T37 >::type arg37 , typename detail::call_param<T38 >::type arg38 , typename detail::call_param<T39 >::type arg39 , typename detail::call_param<T40 >::type arg40 , typename detail::call_param<T41 >::type arg41 , typename detail::call_param<T42 >::type arg42 , typename detail::call_param<T43 >::type arg43 , typename detail::call_param<T44 >::type arg44 , typename detail::call_param<T45 >::type arg45 , typename detail::call_param<T46 >::type arg46)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44 , arg45 , arg46) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42 , typename U43 , typename U44 , typename U45 , typename U46>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43 , U44 , U45 , U46> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42 , typename U43 , typename U44 , typename U45 , typename U46>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43 , U44 , U45 , U46> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36 , typename detail::call_param<T37 >::type arg37 , typename detail::call_param<T38 >::type arg38 , typename detail::call_param<T39 >::type arg39 , typename detail::call_param<T40 >::type arg40 , typename detail::call_param<T41 >::type arg41 , typename detail::call_param<T42 >::type arg42 , typename detail::call_param<T43 >::type arg43 , typename detail::call_param<T44 >::type arg44 , typename detail::call_param<T45 >::type arg45 , typename detail::call_param<T46 >::type arg46 , typename detail::call_param<T47 >::type arg47)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44 , arg45 , arg46 , arg47) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42 , typename U43 , typename U44 , typename U45 , typename U46 , typename U47>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43 , U44 , U45 , U46 , U47> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42 , typename U43 , typename U44 , typename U45 , typename U46 , typename U47>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43 , U44 , U45 , U46 , U47> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36 , typename detail::call_param<T37 >::type arg37 , typename detail::call_param<T38 >::type arg38 , typename detail::call_param<T39 >::type arg39 , typename detail::call_param<T40 >::type arg40 , typename detail::call_param<T41 >::type arg41 , typename detail::call_param<T42 >::type arg42 , typename detail::call_param<T43 >::type arg43 , typename detail::call_param<T44 >::type arg44 , typename detail::call_param<T45 >::type arg45 , typename detail::call_param<T46 >::type arg46 , typename detail::call_param<T47 >::type arg47 , typename detail::call_param<T48 >::type arg48)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44 , arg45 , arg46 , arg47 , arg48) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42 , typename U43 , typename U44 , typename U45 , typename U46 , typename U47 , typename U48>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43 , U44 , U45 , U46 , U47 , U48> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42 , typename U43 , typename U44 , typename U45 , typename U46 , typename U47 , typename U48>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43 , U44 , U45 , U46 , U47 , U48> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+    BOOST_FUSION_GPU_ENABLED
+    tuple(typename detail::call_param<T0 >::type arg0 , typename detail::call_param<T1 >::type arg1 , typename detail::call_param<T2 >::type arg2 , typename detail::call_param<T3 >::type arg3 , typename detail::call_param<T4 >::type arg4 , typename detail::call_param<T5 >::type arg5 , typename detail::call_param<T6 >::type arg6 , typename detail::call_param<T7 >::type arg7 , typename detail::call_param<T8 >::type arg8 , typename detail::call_param<T9 >::type arg9 , typename detail::call_param<T10 >::type arg10 , typename detail::call_param<T11 >::type arg11 , typename detail::call_param<T12 >::type arg12 , typename detail::call_param<T13 >::type arg13 , typename detail::call_param<T14 >::type arg14 , typename detail::call_param<T15 >::type arg15 , typename detail::call_param<T16 >::type arg16 , typename detail::call_param<T17 >::type arg17 , typename detail::call_param<T18 >::type arg18 , typename detail::call_param<T19 >::type arg19 , typename detail::call_param<T20 >::type arg20 , typename detail::call_param<T21 >::type arg21 , typename detail::call_param<T22 >::type arg22 , typename detail::call_param<T23 >::type arg23 , typename detail::call_param<T24 >::type arg24 , typename detail::call_param<T25 >::type arg25 , typename detail::call_param<T26 >::type arg26 , typename detail::call_param<T27 >::type arg27 , typename detail::call_param<T28 >::type arg28 , typename detail::call_param<T29 >::type arg29 , typename detail::call_param<T30 >::type arg30 , typename detail::call_param<T31 >::type arg31 , typename detail::call_param<T32 >::type arg32 , typename detail::call_param<T33 >::type arg33 , typename detail::call_param<T34 >::type arg34 , typename detail::call_param<T35 >::type arg35 , typename detail::call_param<T36 >::type arg36 , typename detail::call_param<T37 >::type arg37 , typename detail::call_param<T38 >::type arg38 , typename detail::call_param<T39 >::type arg39 , typename detail::call_param<T40 >::type arg40 , typename detail::call_param<T41 >::type arg41 , typename detail::call_param<T42 >::type arg42 , typename detail::call_param<T43 >::type arg43 , typename detail::call_param<T44 >::type arg44 , typename detail::call_param<T45 >::type arg45 , typename detail::call_param<T46 >::type arg46 , typename detail::call_param<T47 >::type arg47 , typename detail::call_param<T48 >::type arg48 , typename detail::call_param<T49 >::type arg49)
+        : base_type(arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44 , arg45 , arg46 , arg47 , arg48 , arg49) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42 , typename U43 , typename U44 , typename U45 , typename U46 , typename U47 , typename U48 , typename U49>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43 , U44 , U45 , U46 , U47 , U48 , U49> const& rhs)
+        : base_type(rhs) {}
+    template <typename U0 , typename U1 , typename U2 , typename U3 , typename U4 , typename U5 , typename U6 , typename U7 , typename U8 , typename U9 , typename U10 , typename U11 , typename U12 , typename U13 , typename U14 , typename U15 , typename U16 , typename U17 , typename U18 , typename U19 , typename U20 , typename U21 , typename U22 , typename U23 , typename U24 , typename U25 , typename U26 , typename U27 , typename U28 , typename U29 , typename U30 , typename U31 , typename U32 , typename U33 , typename U34 , typename U35 , typename U36 , typename U37 , typename U38 , typename U39 , typename U40 , typename U41 , typename U42 , typename U43 , typename U44 , typename U45 , typename U46 , typename U47 , typename U48 , typename U49>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<U0 , U1 , U2 , U3 , U4 , U5 , U6 , U7 , U8 , U9 , U10 , U11 , U12 , U13 , U14 , U15 , U16 , U17 , U18 , U19 , U20 , U21 , U22 , U23 , U24 , U25 , U26 , U27 , U28 , U29 , U30 , U31 , U32 , U33 , U34 , U35 , U36 , U37 , U38 , U39 , U40 , U41 , U42 , U43 , U44 , U45 , U46 , U47 , U48 , U49> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+        template <typename T>
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(T const& rhs)
+        {
+            base_type::operator=(rhs);
+            return *this;
+        }
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(tuple const& rhs)
+        {
+            base_type::operator=(static_cast<base_type const&>(rhs));
+            return *this;
+        }
+        template <typename U1, typename U2>
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(std::pair<U1, U2> const& rhs)
+        {
+            base_type::operator=(rhs);
+            return *this;
+        }
+    };
+    template <typename Tuple>
+    struct tuple_size : result_of::size<Tuple> {};
+    template <int N, typename Tuple>
+    struct tuple_element : result_of::value_at_c<Tuple, N> {};
+    template <int N, typename Tuple>
+    BOOST_FUSION_GPU_ENABLED
+    inline typename
+        lazy_disable_if<
+            is_const<Tuple>
+          , result_of::at_c<Tuple, N>
+        >::type
+    get(Tuple& tup)
+    {
+        return at_c<N>(tup);
+    }
+    template <int N, typename Tuple>
+    BOOST_FUSION_GPU_ENABLED
+    inline typename result_of::at_c<Tuple const, N>::type
+    get(Tuple const& tup)
+    {
+        return at_c<N>(tup);
+    }
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple50_fwd.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple50_fwd.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..18fd75c4083ae237b3a34e406a49254f238e7927
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple50_fwd.hpp
@@ -0,0 +1,16 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    struct void_;
+    template <
+        typename T0 = void_ , typename T1 = void_ , typename T2 = void_ , typename T3 = void_ , typename T4 = void_ , typename T5 = void_ , typename T6 = void_ , typename T7 = void_ , typename T8 = void_ , typename T9 = void_ , typename T10 = void_ , typename T11 = void_ , typename T12 = void_ , typename T13 = void_ , typename T14 = void_ , typename T15 = void_ , typename T16 = void_ , typename T17 = void_ , typename T18 = void_ , typename T19 = void_ , typename T20 = void_ , typename T21 = void_ , typename T22 = void_ , typename T23 = void_ , typename T24 = void_ , typename T25 = void_ , typename T26 = void_ , typename T27 = void_ , typename T28 = void_ , typename T29 = void_ , typename T30 = void_ , typename T31 = void_ , typename T32 = void_ , typename T33 = void_ , typename T34 = void_ , typename T35 = void_ , typename T36 = void_ , typename T37 = void_ , typename T38 = void_ , typename T39 = void_ , typename T40 = void_ , typename T41 = void_ , typename T42 = void_ , typename T43 = void_ , typename T44 = void_ , typename T45 = void_ , typename T46 = void_ , typename T47 = void_ , typename T48 = void_ , typename T49 = void_
+    >
+    struct tuple;
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_fwd.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_fwd.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..234936c587d073fb41277c0abe018d4962ba41db
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_fwd.hpp
@@ -0,0 +1,21 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+#if FUSION_MAX_VECTOR_SIZE <= 10
+#include <boost/fusion/tuple/detail/preprocessed/tuple10_fwd.hpp>
+#elif FUSION_MAX_VECTOR_SIZE <= 20
+#include <boost/fusion/tuple/detail/preprocessed/tuple20_fwd.hpp>
+#elif FUSION_MAX_VECTOR_SIZE <= 30
+#include <boost/fusion/tuple/detail/preprocessed/tuple30_fwd.hpp>
+#elif FUSION_MAX_VECTOR_SIZE <= 40
+#include <boost/fusion/tuple/detail/preprocessed/tuple40_fwd.hpp>
+#elif FUSION_MAX_VECTOR_SIZE <= 50
+#include <boost/fusion/tuple/detail/preprocessed/tuple50_fwd.hpp>
+#else
+#error "FUSION_MAX_VECTOR_SIZE out of bounds for preprocessed headers"
+#endif
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5898c6b978455d207cefbbabec19a3949ed04d36
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie.hpp
@@ -0,0 +1,21 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+#if FUSION_MAX_VECTOR_SIZE <= 10
+#include <boost/fusion/tuple/detail/preprocessed/tuple_tie10.hpp>
+#elif FUSION_MAX_VECTOR_SIZE <= 20
+#include <boost/fusion/tuple/detail/preprocessed/tuple_tie20.hpp>
+#elif FUSION_MAX_VECTOR_SIZE <= 30
+#include <boost/fusion/tuple/detail/preprocessed/tuple_tie30.hpp>
+#elif FUSION_MAX_VECTOR_SIZE <= 40
+#include <boost/fusion/tuple/detail/preprocessed/tuple_tie40.hpp>
+#elif FUSION_MAX_VECTOR_SIZE <= 50
+#include <boost/fusion/tuple/detail/preprocessed/tuple_tie50.hpp>
+#else
+#error "FUSION_MAX_VECTOR_SIZE out of bounds for preprocessed headers"
+#endif
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie10.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie10.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..67ec63b78e3be76df89b5a1386faa6c3eb58f39c
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie10.hpp
@@ -0,0 +1,91 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    template <typename T0>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0&>
+    tie(T0 & arg0)
+    {
+        return tuple<T0&>(
+            arg0);
+    }
+    template <typename T0 , typename T1>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1&>
+    tie(T0 & arg0 , T1 & arg1)
+    {
+        return tuple<T0& , T1&>(
+            arg0 , arg1);
+    }
+    template <typename T0 , typename T1 , typename T2>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2)
+    {
+        return tuple<T0& , T1& , T2&>(
+            arg0 , arg1 , arg2);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3)
+    {
+        return tuple<T0& , T1& , T2& , T3&>(
+            arg0 , arg1 , arg2 , arg3);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4&>(
+            arg0 , arg1 , arg2 , arg3 , arg4);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9);
+    }
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie20.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie20.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..37581f20c502c48f1d3550959b83eb9535c5335e
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie20.hpp
@@ -0,0 +1,171 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    template <typename T0>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0&>
+    tie(T0 & arg0)
+    {
+        return tuple<T0&>(
+            arg0);
+    }
+    template <typename T0 , typename T1>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1&>
+    tie(T0 & arg0 , T1 & arg1)
+    {
+        return tuple<T0& , T1&>(
+            arg0 , arg1);
+    }
+    template <typename T0 , typename T1 , typename T2>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2)
+    {
+        return tuple<T0& , T1& , T2&>(
+            arg0 , arg1 , arg2);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3)
+    {
+        return tuple<T0& , T1& , T2& , T3&>(
+            arg0 , arg1 , arg2 , arg3);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4&>(
+            arg0 , arg1 , arg2 , arg3 , arg4);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19);
+    }
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie30.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie30.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d81cb0cdd62e4b90fdb6874d311feeb024285a4b
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie30.hpp
@@ -0,0 +1,251 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    template <typename T0>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0&>
+    tie(T0 & arg0)
+    {
+        return tuple<T0&>(
+            arg0);
+    }
+    template <typename T0 , typename T1>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1&>
+    tie(T0 & arg0 , T1 & arg1)
+    {
+        return tuple<T0& , T1&>(
+            arg0 , arg1);
+    }
+    template <typename T0 , typename T1 , typename T2>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2)
+    {
+        return tuple<T0& , T1& , T2&>(
+            arg0 , arg1 , arg2);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3)
+    {
+        return tuple<T0& , T1& , T2& , T3&>(
+            arg0 , arg1 , arg2 , arg3);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4&>(
+            arg0 , arg1 , arg2 , arg3 , arg4);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29);
+    }
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie40.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie40.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..69eb0d8ddfb166a9c802e3fa942fea1112ff5705
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie40.hpp
@@ -0,0 +1,331 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    template <typename T0>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0&>
+    tie(T0 & arg0)
+    {
+        return tuple<T0&>(
+            arg0);
+    }
+    template <typename T0 , typename T1>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1&>
+    tie(T0 & arg0 , T1 & arg1)
+    {
+        return tuple<T0& , T1&>(
+            arg0 , arg1);
+    }
+    template <typename T0 , typename T1 , typename T2>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2)
+    {
+        return tuple<T0& , T1& , T2&>(
+            arg0 , arg1 , arg2);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3)
+    {
+        return tuple<T0& , T1& , T2& , T3&>(
+            arg0 , arg1 , arg2 , arg3);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4&>(
+            arg0 , arg1 , arg2 , arg3 , arg4);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36 , T37 & arg37)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36 , T37 & arg37 , T38 & arg38)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36 , T37 & arg37 , T38 & arg38 , T39 & arg39)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39);
+    }
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie50.hpp b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie50.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a024e5731cf4ad849d529b9136825af34af1f108
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/preprocessed/tuple_tie50.hpp
@@ -0,0 +1,411 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+namespace boost { namespace fusion
+{
+    template <typename T0>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0&>
+    tie(T0 & arg0)
+    {
+        return tuple<T0&>(
+            arg0);
+    }
+    template <typename T0 , typename T1>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1&>
+    tie(T0 & arg0 , T1 & arg1)
+    {
+        return tuple<T0& , T1&>(
+            arg0 , arg1);
+    }
+    template <typename T0 , typename T1 , typename T2>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2)
+    {
+        return tuple<T0& , T1& , T2&>(
+            arg0 , arg1 , arg2);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3)
+    {
+        return tuple<T0& , T1& , T2& , T3&>(
+            arg0 , arg1 , arg2 , arg3);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4&>(
+            arg0 , arg1 , arg2 , arg3 , arg4);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36 , T37 & arg37)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36 , T37 & arg37 , T38 & arg38)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36 , T37 & arg37 , T38 & arg38 , T39 & arg39)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36 , T37 & arg37 , T38 & arg38 , T39 & arg39 , T40 & arg40)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36 , T37 & arg37 , T38 & arg38 , T39 & arg39 , T40 & arg40 , T41 & arg41)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41 , typename T42>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41& , T42&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36 , T37 & arg37 , T38 & arg38 , T39 & arg39 , T40 & arg40 , T41 & arg41 , T42 & arg42)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41& , T42&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41 , typename T42 , typename T43>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41& , T42& , T43&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36 , T37 & arg37 , T38 & arg38 , T39 & arg39 , T40 & arg40 , T41 & arg41 , T42 & arg42 , T43 & arg43)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41& , T42& , T43&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41 , typename T42 , typename T43 , typename T44>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41& , T42& , T43& , T44&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36 , T37 & arg37 , T38 & arg38 , T39 & arg39 , T40 & arg40 , T41 & arg41 , T42 & arg42 , T43 & arg43 , T44 & arg44)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41& , T42& , T43& , T44&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41 , typename T42 , typename T43 , typename T44 , typename T45>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41& , T42& , T43& , T44& , T45&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36 , T37 & arg37 , T38 & arg38 , T39 & arg39 , T40 & arg40 , T41 & arg41 , T42 & arg42 , T43 & arg43 , T44 & arg44 , T45 & arg45)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41& , T42& , T43& , T44& , T45&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44 , arg45);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41 , typename T42 , typename T43 , typename T44 , typename T45 , typename T46>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41& , T42& , T43& , T44& , T45& , T46&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36 , T37 & arg37 , T38 & arg38 , T39 & arg39 , T40 & arg40 , T41 & arg41 , T42 & arg42 , T43 & arg43 , T44 & arg44 , T45 & arg45 , T46 & arg46)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41& , T42& , T43& , T44& , T45& , T46&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44 , arg45 , arg46);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41 , typename T42 , typename T43 , typename T44 , typename T45 , typename T46 , typename T47>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41& , T42& , T43& , T44& , T45& , T46& , T47&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36 , T37 & arg37 , T38 & arg38 , T39 & arg39 , T40 & arg40 , T41 & arg41 , T42 & arg42 , T43 & arg43 , T44 & arg44 , T45 & arg45 , T46 & arg46 , T47 & arg47)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41& , T42& , T43& , T44& , T45& , T46& , T47&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44 , arg45 , arg46 , arg47);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41 , typename T42 , typename T43 , typename T44 , typename T45 , typename T46 , typename T47 , typename T48>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41& , T42& , T43& , T44& , T45& , T46& , T47& , T48&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36 , T37 & arg37 , T38 & arg38 , T39 & arg39 , T40 & arg40 , T41 & arg41 , T42 & arg42 , T43 & arg43 , T44 & arg44 , T45 & arg45 , T46 & arg46 , T47 & arg47 , T48 & arg48)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41& , T42& , T43& , T44& , T45& , T46& , T47& , T48&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44 , arg45 , arg46 , arg47 , arg48);
+    }
+    template <typename T0 , typename T1 , typename T2 , typename T3 , typename T4 , typename T5 , typename T6 , typename T7 , typename T8 , typename T9 , typename T10 , typename T11 , typename T12 , typename T13 , typename T14 , typename T15 , typename T16 , typename T17 , typename T18 , typename T19 , typename T20 , typename T21 , typename T22 , typename T23 , typename T24 , typename T25 , typename T26 , typename T27 , typename T28 , typename T29 , typename T30 , typename T31 , typename T32 , typename T33 , typename T34 , typename T35 , typename T36 , typename T37 , typename T38 , typename T39 , typename T40 , typename T41 , typename T42 , typename T43 , typename T44 , typename T45 , typename T46 , typename T47 , typename T48 , typename T49>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41& , T42& , T43& , T44& , T45& , T46& , T47& , T48& , T49&>
+    tie(T0 & arg0 , T1 & arg1 , T2 & arg2 , T3 & arg3 , T4 & arg4 , T5 & arg5 , T6 & arg6 , T7 & arg7 , T8 & arg8 , T9 & arg9 , T10 & arg10 , T11 & arg11 , T12 & arg12 , T13 & arg13 , T14 & arg14 , T15 & arg15 , T16 & arg16 , T17 & arg17 , T18 & arg18 , T19 & arg19 , T20 & arg20 , T21 & arg21 , T22 & arg22 , T23 & arg23 , T24 & arg24 , T25 & arg25 , T26 & arg26 , T27 & arg27 , T28 & arg28 , T29 & arg29 , T30 & arg30 , T31 & arg31 , T32 & arg32 , T33 & arg33 , T34 & arg34 , T35 & arg35 , T36 & arg36 , T37 & arg37 , T38 & arg38 , T39 & arg39 , T40 & arg40 , T41 & arg41 , T42 & arg42 , T43 & arg43 , T44 & arg44 , T45 & arg45 , T46 & arg46 , T47 & arg47 , T48 & arg48 , T49 & arg49)
+    {
+        return tuple<T0& , T1& , T2& , T3& , T4& , T5& , T6& , T7& , T8& , T9& , T10& , T11& , T12& , T13& , T14& , T15& , T16& , T17& , T18& , T19& , T20& , T21& , T22& , T23& , T24& , T25& , T26& , T27& , T28& , T29& , T30& , T31& , T32& , T33& , T34& , T35& , T36& , T37& , T38& , T39& , T40& , T41& , T42& , T43& , T44& , T45& , T46& , T47& , T48& , T49&>(
+            arg0 , arg1 , arg2 , arg3 , arg4 , arg5 , arg6 , arg7 , arg8 , arg9 , arg10 , arg11 , arg12 , arg13 , arg14 , arg15 , arg16 , arg17 , arg18 , arg19 , arg20 , arg21 , arg22 , arg23 , arg24 , arg25 , arg26 , arg27 , arg28 , arg29 , arg30 , arg31 , arg32 , arg33 , arg34 , arg35 , arg36 , arg37 , arg38 , arg39 , arg40 , arg41 , arg42 , arg43 , arg44 , arg45 , arg46 , arg47 , arg48 , arg49);
+    }
+}}
diff --git a/ThirdParty/boost/fusion/tuple/detail/tuple.hpp b/ThirdParty/boost/fusion/tuple/detail/tuple.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..45408f0652b1b19f1fd4d06a3c9acf3b0bfa677d
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/tuple.hpp
@@ -0,0 +1,122 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_TUPLE_10032005_0810)
+#define FUSION_TUPLE_10032005_0810
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/tuple/detail/tuple_fwd.hpp>
+#include <boost/fusion/container/vector/vector.hpp>
+#include <boost/fusion/sequence/intrinsic/size.hpp>
+#include <boost/fusion/sequence/intrinsic/value_at.hpp>
+#include <boost/fusion/sequence/intrinsic/at.hpp>
+#include <boost/fusion/sequence/comparison.hpp>
+#include <boost/fusion/sequence/io.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/config/no_tr1/utility.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/tuple/detail/preprocessed/tuple.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/tuple" FUSION_MAX_VECTOR_SIZE_STR ".hpp")
+#endif
+
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+    template <BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, typename T)>
+    struct tuple : vector<BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, T)>
+    {
+        typedef vector<
+            BOOST_PP_ENUM_PARAMS(FUSION_MAX_VECTOR_SIZE, T)>
+        base_type;
+
+        BOOST_FUSION_GPU_ENABLED tuple()
+            : base_type() {}
+
+        BOOST_FUSION_GPU_ENABLED tuple(tuple const& rhs)
+            : base_type(static_cast<base_type const&>(rhs)) {}
+
+        template <typename U1, typename U2>
+        BOOST_FUSION_GPU_ENABLED
+        tuple(std::pair<U1, U2> const& rhs)
+            : base_type(rhs) {}
+
+        #include <boost/fusion/tuple/detail/tuple_expand.hpp>
+
+        template <typename T>
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(T const& rhs)
+        {
+            base_type::operator=(rhs);
+            return *this;
+        }
+
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(tuple const& rhs)
+        {
+            base_type::operator=(static_cast<base_type const&>(rhs));
+            return *this;
+        }
+
+        template <typename U1, typename U2>
+        BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(std::pair<U1, U2> const& rhs)
+        {
+            base_type::operator=(rhs);
+            return *this;
+        }
+    };
+
+    template <typename Tuple>
+    struct tuple_size : result_of::size<Tuple> {};
+
+    template <int N, typename Tuple>
+    struct tuple_element : result_of::value_at_c<Tuple, N> {};
+
+    template <int N, typename Tuple>
+    BOOST_FUSION_GPU_ENABLED
+    inline typename
+        lazy_disable_if<
+            is_const<Tuple>
+          , result_of::at_c<Tuple, N>
+        >::type
+    get(Tuple& tup)
+    {
+        return at_c<N>(tup);
+    }
+
+    template <int N, typename Tuple>
+    BOOST_FUSION_GPU_ENABLED
+    inline typename result_of::at_c<Tuple const, N>::type
+    get(Tuple const& tup)
+    {
+        return at_c<N>(tup);
+    }
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+
diff --git a/ThirdParty/boost/fusion/tuple/detail/tuple_expand.hpp b/ThirdParty/boost/fusion/tuple/detail/tuple_expand.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3909f647b8541e674f62b23830562f9049146e6c
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/tuple_expand.hpp
@@ -0,0 +1,53 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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_PP_IS_ITERATING
+#if !defined(FUSION_TUPLE_EXPAND_10032005_0815)
+#define FUSION_TUPLE_EXPAND_10032005_0815
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+
+#define BOOST_PP_FILENAME_1 \
+    <boost/fusion/tuple/detail/tuple_expand.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
+#include BOOST_PP_ITERATE()
+
+#endif
+#else // defined(BOOST_PP_IS_ITERATING)
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#define N BOOST_PP_ITERATION()
+
+    BOOST_FUSION_GPU_ENABLED
+#if N == 1
+    explicit
+#endif
+    tuple(BOOST_PP_ENUM_BINARY_PARAMS(
+        N, typename detail::call_param<T, >::type arg))
+        : base_type(BOOST_PP_ENUM_PARAMS(N, arg)) {}
+
+    template <BOOST_PP_ENUM_PARAMS(N, typename U)>
+    BOOST_FUSION_GPU_ENABLED
+    tuple(tuple<BOOST_PP_ENUM_PARAMS(N, U)> const& rhs)
+        : base_type(rhs) {}
+
+    template <BOOST_PP_ENUM_PARAMS(N, typename U)>
+    BOOST_FUSION_GPU_ENABLED
+    tuple& operator=(tuple<BOOST_PP_ENUM_PARAMS(N, U)> const& rhs)
+    {
+        base_type::operator=(rhs);
+        return *this;
+    }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
diff --git a/ThirdParty/boost/fusion/tuple/detail/tuple_fwd.hpp b/ThirdParty/boost/fusion/tuple/detail/tuple_fwd.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ef6bdfe8b60608b9318b0ac8dc51b414f73b7dc4
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/tuple_fwd.hpp
@@ -0,0 +1,52 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+==============================================================================*/
+#if !defined(FUSION_TUPLE_FORWARD_10032005_0956)
+#define FUSION_TUPLE_FORWARD_10032005_0956
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/container/vector/detail/cpp03/limits.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/tuple/detail/preprocessed/tuple_fwd.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/tuple" FUSION_MAX_VECTOR_SIZE_STR "_fwd.hpp")
+#endif
+
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+    struct void_;
+
+    template <
+        BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+            FUSION_MAX_VECTOR_SIZE, typename T, void_)
+    >
+    struct tuple;
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+
diff --git a/ThirdParty/boost/fusion/tuple/detail/tuple_tie.hpp b/ThirdParty/boost/fusion/tuple/detail/tuple_tie.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b650d1cc1604898e786322ce091b652fbbb20200
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/detail/tuple_tie.hpp
@@ -0,0 +1,76 @@
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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_PP_IS_ITERATING
+#if !defined(FUSION_TUPLE_TIE_10032005_0846)
+#define FUSION_TUPLE_TIE_10032005_0846
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/fusion/tuple/detail/tuple.hpp>
+
+#if !defined(BOOST_FUSION_DONT_USE_PREPROCESSED_FILES)
+#include <boost/fusion/tuple/detail/preprocessed/tuple_tie.hpp>
+#else
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 2, line: 0, output: "preprocessed/tuple_tie" FUSION_MAX_VECTOR_SIZE_STR ".hpp")
+#endif
+
+/*=============================================================================
+    Copyright (c) 2001-2011 Joel de Guzman
+
+    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)
+
+    This is an auto-generated file. Do not edit!
+==============================================================================*/
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(preserve: 1)
+#endif
+
+namespace boost { namespace fusion
+{
+#define BOOST_FUSION_REF(z, n, data) BOOST_PP_CAT(T, n)&
+
+#define BOOST_PP_FILENAME_1 <boost/fusion/tuple/detail/tuple_tie.hpp>
+#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
+#include BOOST_PP_ITERATE()
+
+#undef BOOST_FUSION_REF
+
+}}
+
+#if defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES)
+#pragma wave option(output: null)
+#endif
+
+#endif // BOOST_FUSION_DONT_USE_PREPROCESSED_FILES
+
+#endif
+#else // defined(BOOST_PP_IS_ITERATING)
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Preprocessor vertical repetition code
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#define N BOOST_PP_ITERATION()
+
+    template <BOOST_PP_ENUM_PARAMS(N, typename T)>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)>
+    tie(BOOST_PP_ENUM_BINARY_PARAMS(N, T, & arg))
+    {
+        return tuple<BOOST_PP_ENUM(N, BOOST_FUSION_REF, _)>(
+            BOOST_PP_ENUM_PARAMS(N, arg));
+    }
+
+#undef N
+#endif // defined(BOOST_PP_IS_ITERATING)
+
diff --git a/ThirdParty/boost/fusion/tuple/make_tuple.hpp b/ThirdParty/boost/fusion/tuple/make_tuple.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e5cbb3b2ac8a3243dc48d52266bada36058f7e87
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/make_tuple.hpp
@@ -0,0 +1,50 @@
+/*=============================================================================
+    Copyright (c) 2014 Kohei Takahashi
+
+    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 FUSION_MAKE_TUPLE_14122014_0048
+#define FUSION_MAKE_TUPLE_14122014_0048
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/tuple/tuple_fwd.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// With no variadics, we will use the C++03 version
+///////////////////////////////////////////////////////////////////////////////
+#if !defined(BOOST_FUSION_HAS_VARIADIC_TUPLE)
+# include <boost/fusion/tuple/detail/make_tuple.hpp>
+#else
+
+///////////////////////////////////////////////////////////////////////////////
+// C++11 interface
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/fusion/support/detail/as_fusion_element.hpp>
+#include <boost/fusion/tuple/tuple.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/remove_const.hpp>
+
+namespace boost { namespace fusion
+{
+    template <typename ...T>
+    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+    inline tuple<typename detail::as_fusion_element<
+        typename remove_const<
+            typename remove_reference<T>::type
+        >::type
+    >::type...>
+    make_tuple(T&&... arg)
+    {
+        typedef tuple<typename detail::as_fusion_element<
+            typename remove_const<
+                typename remove_reference<T>::type
+            >::type
+        >::type...> result_type;
+        return result_type(std::forward<T>(arg)...);
+    }
+}}
+
+#endif
+#endif
+
diff --git a/ThirdParty/boost/fusion/tuple/tuple.hpp b/ThirdParty/boost/fusion/tuple/tuple.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..16b855113c8d537cc088240f21ee9d9c61e6994a
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/tuple.hpp
@@ -0,0 +1,127 @@
+/*=============================================================================
+    Copyright (c) 2014-2015 Kohei Takahashi
+
+    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 FUSION_TUPLE_14122014_0102
+#define FUSION_TUPLE_14122014_0102
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/tuple/tuple_fwd.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// With no variadics, we will use the C++03 version
+///////////////////////////////////////////////////////////////////////////////
+#if !defined(BOOST_FUSION_HAS_VARIADIC_TUPLE)
+# include <boost/fusion/tuple/detail/tuple.hpp>
+#else
+
+///////////////////////////////////////////////////////////////////////////////
+// C++11 interface
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/core/enable_if.hpp>
+#include <boost/fusion/container/vector/vector.hpp>
+#include <boost/fusion/sequence/intrinsic/size.hpp>
+#include <boost/fusion/sequence/intrinsic/value_at.hpp>
+#include <boost/fusion/sequence/intrinsic/at.hpp>
+#include <boost/fusion/sequence/comparison.hpp>
+#include <boost/fusion/sequence/io.hpp>
+#include <boost/fusion/support/detail/and.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <utility>
+
+namespace boost { namespace fusion
+{
+    template <typename ...T>
+    struct tuple
+        : vector_detail::vector_data<
+              typename detail::make_index_sequence<sizeof...(T)>::type
+            , T...
+          >
+    {
+        typedef vector_detail::vector_data<
+            typename detail::make_index_sequence<sizeof...(T)>::type
+          , T...
+        > base;
+
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        BOOST_DEFAULTED_FUNCTION(tuple(), {})
+
+        template <
+            typename ...U
+          , typename = typename boost::enable_if_c<
+                sizeof...(U) >= sizeof...(T)
+            >::type
+        >
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        tuple(tuple<U...> const& other)
+            : base(vector_detail::each_elem(), other) {}
+
+        template <
+            typename ...U
+          , typename = typename boost::enable_if_c<
+                sizeof...(U) >= sizeof...(T)
+            >::type
+        >
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        tuple(tuple<U...>&& other)
+            : base(vector_detail::each_elem(), std::move(other)) {}
+
+        template <
+            typename ...U
+          , typename = typename boost::enable_if_c<(
+                fusion::detail::and_<is_convertible<U, T>...>::value &&
+                sizeof...(U) >= 1
+            )>::type
+        >
+        /*BOOST_CONSTEXPR*/ BOOST_FUSION_GPU_ENABLED
+        explicit
+        tuple(U&&... args)
+            : base(vector_detail::each_elem(), std::forward<U>(args)...) {}
+
+        template<typename U1, typename U2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        tuple(std::pair<U1, U2> const& other)
+            : base(vector_detail::each_elem(), other.first, other.second) {}
+
+        template<typename U1, typename U2>
+        BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        tuple(std::pair<U1, U2>&& other)
+            : base(vector_detail::each_elem(), std::move(other.first), std::move(other.second)) {}
+
+        template<typename U>
+        BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+        tuple& operator=(U&& rhs)
+        {
+            base::assign_sequence(std::forward<U>(rhs));
+            return *this;
+        }
+    };
+
+    template <typename Tuple>
+    struct tuple_size : result_of::size<Tuple> {};
+
+    template <int N, typename Tuple>
+    struct tuple_element : result_of::value_at_c<Tuple, N> {};
+
+    template <int N, typename Tuple>
+    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+    inline typename result_of::at_c<Tuple, N>::type
+    get(Tuple& tup)
+    {
+        return at_c<N>(tup);
+    }
+
+    template <int N, typename Tuple>
+    BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED
+    inline typename result_of::at_c<Tuple const, N>::type
+    get(Tuple const& tup)
+    {
+        return at_c<N>(tup);
+    }
+}}
+
+#endif
+#endif
+
diff --git a/ThirdParty/boost/fusion/tuple/tuple_fwd.hpp b/ThirdParty/boost/fusion/tuple/tuple_fwd.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b763acd52fe58e791c33c25a696da6657e57438f
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/tuple_fwd.hpp
@@ -0,0 +1,43 @@
+/*=============================================================================
+    Copyright (c) 2014-2015 Kohei Takahashi
+
+    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 FUSION_TUPLE_FORWARD_14122014_0051
+#define FUSION_TUPLE_FORWARD_14122014_0051
+
+#include <boost/config.hpp>
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/container/vector/detail/config.hpp>
+
+#if  !defined(BOOST_FUSION_HAS_VARIADIC_VECTOR) \
+  || (defined(__WAVE__) && defined(BOOST_FUSION_CREATE_PREPROCESSED_FILES))
+# if defined(BOOST_FUSION_HAS_VARIADIC_TUPLE)
+#   undef BOOST_FUSION_HAS_VARIADIC_TUPLE
+# endif
+#else
+# if !defined(BOOST_FUSION_HAS_VARIADIC_TUPLE)
+#   define BOOST_FUSION_HAS_VARIADIC_TUPLE
+# endif
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// With no variadics, we will use the C++03 version
+///////////////////////////////////////////////////////////////////////////////
+#if !defined(BOOST_FUSION_HAS_VARIADIC_TUPLE)
+# include <boost/fusion/tuple/detail/tuple_fwd.hpp>
+#else
+
+///////////////////////////////////////////////////////////////////////////////
+// C++11 interface
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace fusion
+{
+    template <typename ...T>
+    struct tuple;
+}}
+
+#endif
+#endif
+
diff --git a/ThirdParty/boost/fusion/tuple/tuple_tie.hpp b/ThirdParty/boost/fusion/tuple/tuple_tie.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a07dc0a43e4e0f1a8d80aa19a99a04b988a02b6d
--- /dev/null
+++ b/ThirdParty/boost/fusion/tuple/tuple_tie.hpp
@@ -0,0 +1,38 @@
+/*=============================================================================
+    Copyright (c) 2014 Kohei Takahashi
+
+    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 FUSION_TUPLE_TIE_14122014_0115
+#define FUSION_TUPLE_TIE_14122014_0115
+
+#include <boost/fusion/support/config.hpp>
+#include <boost/fusion/tuple/tuple_fwd.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// With no variadics, we will use the C++03 version
+///////////////////////////////////////////////////////////////////////////////
+#if !defined(BOOST_FUSION_HAS_VARIADIC_TUPLE)
+# include <boost/fusion/tuple/detail/tuple_tie.hpp>
+#else
+
+///////////////////////////////////////////////////////////////////////////////
+// C++11 interface
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/fusion/tuple/tuple.hpp>
+
+namespace boost { namespace fusion
+{
+    template <typename ...T>
+    BOOST_FUSION_GPU_ENABLED
+    inline tuple<T&...>
+    tie(T&... arg)
+    {
+        return tuple<T&...>(arg...);
+    }
+}}
+
+#endif
+#endif
+
diff --git a/ThirdParty/boost/math/constants/calculate_constants.hpp b/ThirdParty/boost/math/constants/calculate_constants.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..565493b3d30990e4b016bde0ec307e0d1a9872d3
--- /dev/null
+++ b/ThirdParty/boost/math/constants/calculate_constants.hpp
@@ -0,0 +1,1014 @@
+//  Copyright John Maddock 2010, 2012.
+//  Copyright Paul A. Bristow 2011, 2012.
+
+//  Use, modification and distribution are subject to 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_CALCULATE_CONSTANTS_CONSTANTS_INCLUDED
+#define BOOST_MATH_CALCULATE_CONSTANTS_CONSTANTS_INCLUDED
+
+#include <boost/math/special_functions/trunc.hpp>
+
+namespace boost{ namespace math{ namespace constants{ namespace detail{
+
+template <class T>
+template<int N>
+inline T constant_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+
+   return ldexp(acos(T(0)), 1);
+
+   /*
+   // Although this code works well, it's usually more accurate to just call acos
+   // and access the number types own representation of PI which is usually calculated
+   // at slightly higher precision...
+
+   T result;
+   T a = 1;
+   T b;
+   T A(a);
+   T B = 0.5f;
+   T D = 0.25f;
+
+   T lim;
+   lim = boost::math::tools::epsilon<T>();
+
+   unsigned k = 1;
+
+   do
+   {
+      result = A + B;
+      result = ldexp(result, -2);
+      b = sqrt(B);
+      a += b;
+      a = ldexp(a, -1);
+      A = a * a;
+      B = A - result;
+      B = ldexp(B, 1);
+      result = A - B;
+      bool neg = boost::math::sign(result) < 0;
+      if(neg)
+         result = -result;
+      if(result <= lim)
+         break;
+      if(neg)
+         result = -result;
+      result = ldexp(result, k - 1);
+      D -= result;
+      ++k;
+      lim = ldexp(lim, 1);
+   }
+   while(true);
+
+   result = B / D;
+   return result;
+   */
+}
+
+template <class T>
+template<int N>
+inline T constant_two_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   return 2 * pi<T, policies::policy<policies::digits2<N> > >();
+}
+
+template <class T> // 2 / pi
+template<int N>
+inline T constant_two_div_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   return 2 / pi<T, policies::policy<policies::digits2<N> > >();
+}
+
+template <class T>  // sqrt(2/pi)
+template <int N>
+inline T constant_root_two_div_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return sqrt((2 / pi<T, policies::policy<policies::digits2<N> > >()));
+}
+
+template <class T>
+template<int N>
+inline T constant_one_div_two_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   return 1 / two_pi<T, policies::policy<policies::digits2<N> > >();
+}
+
+template <class T>
+template<int N>
+inline T constant_root_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return sqrt(pi<T, policies::policy<policies::digits2<N> > >());
+}
+
+template <class T>
+template<int N>
+inline T constant_root_half_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return sqrt(pi<T, policies::policy<policies::digits2<N> > >() / 2);
+}
+
+template <class T>
+template<int N>
+inline T constant_root_two_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return sqrt(two_pi<T, policies::policy<policies::digits2<N> > >());
+}
+
+template <class T>
+template<int N>
+inline T constant_log_root_two_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return log(root_two_pi<T, policies::policy<policies::digits2<N> > >());
+}
+
+template <class T>
+template<int N>
+inline T constant_root_ln_four<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return sqrt(log(static_cast<T>(4)));
+}
+
+template <class T>
+template<int N>
+inline T constant_e<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   //
+   // Although we can clearly calculate this from first principles, this hooks into
+   // T's own notion of e, which hopefully will more accurate than one calculated to
+   // a few epsilon:
+   //
+   BOOST_MATH_STD_USING
+   return exp(static_cast<T>(1));
+}
+
+template <class T>
+template<int N>
+inline T constant_half<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   return static_cast<T>(1) / static_cast<T>(2);
+}
+
+template <class T>
+template<int M>
+inline T constant_euler<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, M>)))
+{
+   BOOST_MATH_STD_USING
+   //
+   // This is the method described in:
+   // "Some New Algorithms for High-Precision Computation of Euler's Constant"
+   // Richard P Brent and Edwin M McMillan.
+   // Mathematics of Computation, Volume 34, Number 149, Jan 1980, pages 305-312.
+   // See equation 17 with p = 2.
+   //
+   T n = 3 + (M ? (std::min)(M, tools::digits<T>()) : tools::digits<T>()) / 4;
+   T lim = M ? ldexp(T(1), 1 - (std::min)(M, tools::digits<T>())) : tools::epsilon<T>();
+   T lnn = log(n);
+   T term = 1;
+   T N = -lnn;
+   T D = 1;
+   T Hk = 0;
+   T one = 1;
+
+   for(unsigned k = 1;; ++k)
+   {
+      term *= n * n;
+      term /= k * k;
+      Hk += one / k;
+      N += term * (Hk - lnn);
+      D += term;
+
+      if(term < D * lim)
+         break;
+   }
+   return N / D;
+}
+
+template <class T>
+template<int N>
+inline T constant_euler_sqr<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+  BOOST_MATH_STD_USING
+  return euler<T, policies::policy<policies::digits2<N> > >()
+     * euler<T, policies::policy<policies::digits2<N> > >();
+}
+
+template <class T>
+template<int N>
+inline T constant_one_div_euler<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+  BOOST_MATH_STD_USING
+  return static_cast<T>(1)
+     / euler<T, policies::policy<policies::digits2<N> > >();
+}
+
+
+template <class T>
+template<int N>
+inline T constant_root_two<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return sqrt(static_cast<T>(2));
+}
+
+
+template <class T>
+template<int N>
+inline T constant_root_three<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return sqrt(static_cast<T>(3));
+}
+
+template <class T>
+template<int N>
+inline T constant_half_root_two<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return sqrt(static_cast<T>(2)) / 2;
+}
+
+template <class T>
+template<int N>
+inline T constant_ln_two<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   //
+   // Although there are good ways to calculate this from scratch, this hooks into
+   // T's own notion of log(2) which will hopefully be accurate to the full precision
+   // of T:
+   //
+   BOOST_MATH_STD_USING
+   return log(static_cast<T>(2));
+}
+
+template <class T>
+template<int N>
+inline T constant_ln_ten<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return log(static_cast<T>(10));
+}
+
+template <class T>
+template<int N>
+inline T constant_ln_ln_two<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return log(log(static_cast<T>(2)));
+}
+
+template <class T>
+template<int N>
+inline T constant_third<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return static_cast<T>(1) / static_cast<T>(3);
+}
+
+template <class T>
+template<int N>
+inline T constant_twothirds<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return static_cast<T>(2) / static_cast<T>(3);
+}
+
+template <class T>
+template<int N>
+inline T constant_two_thirds<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return static_cast<T>(2) / static_cast<T>(3);
+}
+
+template <class T>
+template<int N>
+inline T constant_three_quarters<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return static_cast<T>(3) / static_cast<T>(4);
+}
+
+template <class T>
+template<int N>
+inline T constant_sixth<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+  BOOST_MATH_STD_USING
+  return static_cast<T>(1) / static_cast<T>(6);
+}
+
+// Pi and related constants.
+template <class T>
+template<int N>
+inline T constant_pi_minus_three<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   return pi<T, policies::policy<policies::digits2<N> > >() - static_cast<T>(3);
+}
+
+template <class T>
+template<int N>
+inline T constant_four_minus_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   return static_cast<T>(4) - pi<T, policies::policy<policies::digits2<N> > >();
+}
+
+//template <class T>
+//template<int N>
+//inline T constant_pow23_four_minus_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+//{
+//   BOOST_MATH_STD_USING
+//   return pow(four_minus_pi<T, policies::policy<policies::digits2<N> > >(), static_cast<T>(1.5));
+//}
+
+template <class T>
+template<int N>
+inline T constant_exp_minus_half<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return exp(static_cast<T>(-0.5));
+}
+
+template <class T>
+template<int N>
+inline T constant_exp_minus_one<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+  BOOST_MATH_STD_USING
+  return exp(static_cast<T>(-1.));
+}
+
+template <class T>
+template<int N>
+inline T constant_one_div_root_two<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   return static_cast<T>(1) / root_two<T, policies::policy<policies::digits2<N> > >();
+}
+
+template <class T>
+template<int N>
+inline T constant_one_div_root_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   return static_cast<T>(1) / root_pi<T, policies::policy<policies::digits2<N> > >();
+}
+
+template <class T>
+template<int N>
+inline T constant_one_div_root_two_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   return static_cast<T>(1) / root_two_pi<T, policies::policy<policies::digits2<N> > >();
+}
+
+template <class T>
+template<int N>
+inline T constant_root_one_div_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return sqrt(static_cast<T>(1) / pi<T, policies::policy<policies::digits2<N> > >());
+}
+
+template <class T>
+template<int N>
+inline T constant_four_thirds_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return pi<T, policies::policy<policies::digits2<N> > >() * static_cast<T>(4) / static_cast<T>(3);
+}
+
+template <class T>
+template<int N>
+inline T constant_half_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return pi<T, policies::policy<policies::digits2<N> > >()  / static_cast<T>(2);
+}
+
+
+template <class T>
+template<int N>
+inline T constant_third_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return pi<T, policies::policy<policies::digits2<N> > >()  / static_cast<T>(3);
+}
+
+template <class T>
+template<int N>
+inline T constant_sixth_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return pi<T, policies::policy<policies::digits2<N> > >()  / static_cast<T>(6);
+}
+
+template <class T>
+template<int N>
+inline T constant_two_thirds_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return pi<T, policies::policy<policies::digits2<N> > >() * static_cast<T>(2) / static_cast<T>(3);
+}
+
+template <class T>
+template<int N>
+inline T constant_three_quarters_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return pi<T, policies::policy<policies::digits2<N> > >() * static_cast<T>(3) / static_cast<T>(4);
+}
+
+template <class T>
+template<int N>
+inline T constant_pi_pow_e<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return pow(pi<T, policies::policy<policies::digits2<N> > >(), e<T, policies::policy<policies::digits2<N> > >()); //
+}
+
+template <class T>
+template<int N>
+inline T constant_pi_sqr<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return pi<T, policies::policy<policies::digits2<N> > >()
+   *      pi<T, policies::policy<policies::digits2<N> > >() ; //
+}
+
+template <class T>
+template<int N>
+inline T constant_pi_sqr_div_six<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return pi<T, policies::policy<policies::digits2<N> > >()
+   *      pi<T, policies::policy<policies::digits2<N> > >()
+   / static_cast<T>(6); //
+}
+
+
+template <class T>
+template<int N>
+inline T constant_pi_cubed<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return pi<T, policies::policy<policies::digits2<N> > >()
+   *      pi<T, policies::policy<policies::digits2<N> > >()
+   *      pi<T, policies::policy<policies::digits2<N> > >()
+   ; //
+}
+
+template <class T>
+template<int N>
+inline T constant_cbrt_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return pow(pi<T, policies::policy<policies::digits2<N> > >(), static_cast<T>(1)/ static_cast<T>(3));
+}
+
+template <class T>
+template<int N>
+inline T constant_one_div_cbrt_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return static_cast<T>(1)
+   / pow(pi<T, policies::policy<policies::digits2<N> > >(), static_cast<T>(1)/ static_cast<T>(3));
+}
+
+// Euler's e
+
+template <class T>
+template<int N>
+inline T constant_e_pow_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return pow(e<T, policies::policy<policies::digits2<N> > >(), pi<T, policies::policy<policies::digits2<N> > >()); //
+}
+
+template <class T>
+template<int N>
+inline T constant_root_e<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return sqrt(e<T, policies::policy<policies::digits2<N> > >());
+}
+
+template <class T>
+template<int N>
+inline T constant_log10_e<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return log10(e<T, policies::policy<policies::digits2<N> > >());
+}
+
+template <class T>
+template<int N>
+inline T constant_one_div_log10_e<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return  static_cast<T>(1) /
+     log10(e<T, policies::policy<policies::digits2<N> > >());
+}
+
+// Trigonometric
+
+template <class T>
+template<int N>
+inline T constant_degree<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return pi<T, policies::policy<policies::digits2<N> > >()
+   / static_cast<T>(180)
+   ; //
+}
+
+template <class T>
+template<int N>
+inline T constant_radian<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return static_cast<T>(180)
+   / pi<T, policies::policy<policies::digits2<N> > >()
+   ; //
+}
+
+template <class T>
+template<int N>
+inline T constant_sin_one<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return sin(static_cast<T>(1)) ; //
+}
+
+template <class T>
+template<int N>
+inline T constant_cos_one<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return cos(static_cast<T>(1)) ; //
+}
+
+template <class T>
+template<int N>
+inline T constant_sinh_one<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return sinh(static_cast<T>(1)) ; //
+}
+
+template <class T>
+template<int N>
+inline T constant_cosh_one<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return cosh(static_cast<T>(1)) ; //
+}
+
+template <class T>
+template<int N>
+inline T constant_phi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return (static_cast<T>(1) + sqrt(static_cast<T>(5)) )/static_cast<T>(2) ; //
+}
+
+template <class T>
+template<int N>
+inline T constant_ln_phi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   //return  log(phi<T, policies::policy<policies::digits2<N> > >()); // ???
+   return log((static_cast<T>(1) + sqrt(static_cast<T>(5)) )/static_cast<T>(2) );
+}
+template <class T>
+template<int N>
+inline T constant_one_div_ln_phi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+   return static_cast<T>(1) /
+     log((static_cast<T>(1) + sqrt(static_cast<T>(5)) )/static_cast<T>(2) );
+}
+
+// Zeta
+
+template <class T>
+template<int N>
+inline T constant_zeta_two<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   BOOST_MATH_STD_USING
+
+     return pi<T, policies::policy<policies::digits2<N> > >()
+     *  pi<T, policies::policy<policies::digits2<N> > >()
+     /static_cast<T>(6);
+}
+
+template <class T>
+template<int N>
+inline T constant_zeta_three<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   // http://mathworld.wolfram.com/AperysConstant.html
+   // http://en.wikipedia.org/wiki/Mathematical_constant
+
+   // http://oeis.org/A002117/constant
+   //T zeta3("1.20205690315959428539973816151144999076"
+   // "4986292340498881792271555341838205786313"
+   // "09018645587360933525814619915");
+
+  //"1.202056903159594285399738161511449990, 76498629234049888179227155534183820578631309018645587360933525814619915"  A002117
+  // 1.202056903159594285399738161511449990, 76498629234049888179227155534183820578631309018645587360933525814619915780, +00);
+  //"1.2020569031595942 double
+  // http://www.spaennare.se/SSPROG/ssnum.pdf  // section 11, Algorithm for Apery's constant zeta(3).
+  // Programs to Calculate some Mathematical Constants to Large Precision, Document Version 1.50
+
+  // by Stefan Spannare  September 19, 2007
+  // zeta(3) = 1/64 * sum
+   BOOST_MATH_STD_USING
+   T n_fact=static_cast<T>(1); // build n! for n = 0.
+   T sum = static_cast<double>(77); // Start with n = 0 case.
+   // for n = 0, (77/1) /64 = 1.203125
+   //double lim = std::numeric_limits<double>::epsilon();
+   T lim = N ? ldexp(T(1), 1 - (std::min)(N, tools::digits<T>())) : tools::epsilon<T>();
+   for(unsigned int n = 1; n < 40; ++n)
+   { // three to five decimal digits per term, so 40 should be plenty for 100 decimal digits.
+      //cout << "n = " << n << endl;
+      n_fact *= n; // n!
+      T n_fact_p10 = n_fact * n_fact * n_fact * n_fact * n_fact * n_fact * n_fact * n_fact * n_fact * n_fact; // (n!)^10
+      T num = ((205 * n * n) + (250 * n) + 77) * n_fact_p10; // 205n^2 + 250n + 77
+      // int nn = (2 * n + 1);
+      // T d = factorial(nn); // inline factorial.
+      T d = 1;
+      for(unsigned int i = 1; i <= (n+n + 1); ++i) // (2n + 1)
+      {
+        d *= i;
+      }
+      T den = d * d * d * d * d; // [(2n+1)!]^5
+      //cout << "den = " << den << endl;
+      T term = num/den;
+      if (n % 2 != 0)
+      { //term *= -1;
+        sum -= term;
+      }
+      else
+      {
+        sum += term;
+      }
+      //cout << "term = " << term << endl;
+      //cout << "sum/64  = " << sum/64 << endl;
+      if(abs(term) < lim)
+      {
+         break;
+      }
+   }
+   return sum / 64;
+}
+
+template <class T>
+template<int N>
+inline T constant_catalan<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{ // http://oeis.org/A006752/constant
+  //T c("0.915965594177219015054603514932384110774"
+ //"149374281672134266498119621763019776254769479356512926115106248574");
+
+  // 9.159655941772190150546035149323841107, 74149374281672134266498119621763019776254769479356512926115106248574422619, -01);
+
+   // This is equation (entry) 31 from
+   // http://www-2.cs.cmu.edu/~adamchik/articles/catalan/catalan.htm
+   // See also http://www.mpfr.org/algorithms.pdf
+   BOOST_MATH_STD_USING
+   T k_fact = 1;
+   T tk_fact = 1;
+   T sum = 1;
+   T term;
+   T lim = N ? ldexp(T(1), 1 - (std::min)(N, tools::digits<T>())) : tools::epsilon<T>();
+
+   for(unsigned k = 1;; ++k)
+   {
+      k_fact *= k;
+      tk_fact *= (2 * k) * (2 * k - 1);
+      term = k_fact * k_fact / (tk_fact * (2 * k + 1) * (2 * k + 1));
+      sum += term;
+      if(term < lim)
+      {
+         break;
+      }
+   }
+   return boost::math::constants::pi<T, boost::math::policies::policy<> >()
+      * log(2 + boost::math::constants::root_three<T, boost::math::policies::policy<> >())
+       / 8
+      + 3 * sum / 8;
+}
+
+namespace khinchin_detail{
+
+template <class T>
+T zeta_polynomial_series(T s, T sc, int digits)
+{
+   BOOST_MATH_STD_USING
+   //
+   // This is algorithm 3 from:
+   //
+   // "An Efficient Algorithm for the Riemann Zeta Function", P. Borwein,
+   // Canadian Mathematical Society, Conference Proceedings, 2000.
+   // See: http://www.cecm.sfu.ca/personal/pborwein/PAPERS/P155.pdf
+   //
+   BOOST_MATH_STD_USING
+   int n = (digits * 19) / 53;
+   T sum = 0;
+   T two_n = ldexp(T(1), n);
+   int ej_sign = 1;
+   for(int j = 0; j < n; ++j)
+   {
+      sum += ej_sign * -two_n / pow(T(j + 1), s);
+      ej_sign = -ej_sign;
+   }
+   T ej_sum = 1;
+   T ej_term = 1;
+   for(int j = n; j <= 2 * n - 1; ++j)
+   {
+      sum += ej_sign * (ej_sum - two_n) / pow(T(j + 1), s);
+      ej_sign = -ej_sign;
+      ej_term *= 2 * n - j;
+      ej_term /= j - n + 1;
+      ej_sum += ej_term;
+   }
+   return -sum / (two_n * (1 - pow(T(2), sc)));
+}
+
+template <class T>
+T khinchin(int digits)
+{
+   BOOST_MATH_STD_USING
+   T sum = 0;
+   T term;
+   T lim = ldexp(T(1), 1-digits);
+   T factor = 0;
+   unsigned last_k = 1;
+   T num = 1;
+   for(unsigned n = 1;; ++n)
+   {
+      for(unsigned k = last_k; k <= 2 * n - 1; ++k)
+      {
+         factor += num / k;
+         num = -num;
+      }
+      last_k = 2 * n;
+      term = (zeta_polynomial_series(T(2 * n), T(1 - T(2 * n)), digits) - 1) * factor / n;
+      sum += term;
+      if(term < lim)
+         break;
+   }
+   return exp(sum / boost::math::constants::ln_two<T, boost::math::policies::policy<> >());
+}
+
+}
+
+template <class T>
+template<int N>
+inline T constant_khinchin<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   int n = N ? (std::min)(N, tools::digits<T>()) : tools::digits<T>();
+   return khinchin_detail::khinchin<T>(n);
+}
+
+template <class T>
+template<int N>
+inline T constant_extreme_value_skewness<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{ // from e_float constants.cpp
+  // Mathematica: N[12 Sqrt[6]  Zeta[3]/Pi^3, 1101]
+   BOOST_MATH_STD_USING
+   T ev(12 * sqrt(static_cast<T>(6)) * zeta_three<T, policies::policy<policies::digits2<N> > >()
+    / pi_cubed<T, policies::policy<policies::digits2<N> > >() );
+
+//T ev(
+//"1.1395470994046486574927930193898461120875997958365518247216557100852480077060706857071875468869385150"
+//"1894272048688553376986765366075828644841024041679714157616857834895702411080704529137366329462558680"
+//"2015498788776135705587959418756809080074611906006528647805347822929577145038743873949415294942796280"
+//"0895597703063466053535550338267721294164578901640163603544404938283861127819804918174973533694090594"
+//"3094963822672055237678432023017824416203652657301470473548274848068762500300316769691474974950757965"
+//"8640779777748741897542093874605477776538884083378029488863880220988107155275203245233994097178778984"
+//"3488995668362387892097897322246698071290011857605809901090220903955815127463328974447572119951192970"
+//"3684453635456559086126406960279692862247058250100678008419431185138019869693206366891639436908462809"
+//"9756051372711251054914491837034685476095423926553367264355374652153595857163724698198860485357368964"
+//"3807049634423621246870868566707915720704996296083373077647528285782964567312903914752617978405994377"
+//"9064157147206717895272199736902453130842229559980076472936976287378945035706933650987259357729800315");
+
+  return ev;
+}
+
+namespace detail{
+//
+// Calculation of the Glaisher constant depends upon calculating the
+// derivative of the zeta function at 2, we can then use the relation:
+// zeta'(2) = 1/6 pi^2 [euler + ln(2pi)-12ln(A)]
+// To get the constant A.
+// See equation 45 at http://mathworld.wolfram.com/RiemannZetaFunction.html.
+//
+// The derivative of the zeta function is computed by direct differentiation
+// of the relation:
+// (1-2^(1-s))zeta(s) = SUM(n=0, INF){ (-n)^n / (n+1)^s  }
+// Which gives us 2 slowly converging but alternating sums to compute,
+// for this we use Algorithm 1 from "Convergent Acceleration of Alternating Series",
+// Henri Cohen, Fernando Rodriguez Villegas and Don Zagier, Experimental Mathematics 9:1 (1999).
+// See http://www.math.utexas.edu/users/villegas/publications/conv-accel.pdf
+//
+template <class T>
+T zeta_series_derivative_2(unsigned digits)
+{
+   // Derivative of the series part, evaluated at 2:
+   BOOST_MATH_STD_USING
+   int n = digits * 301 * 13 / 10000;
+   boost::math::itrunc((std::numeric_limits<T>::digits10 + 1) * 1.3);
+   T d = pow(3 + sqrt(T(8)), n);
+   d = (d + 1 / d) / 2;
+   T b = -1;
+   T c = -d;
+   T s = 0;
+   for(int k = 0; k < n; ++k)
+   {
+      T a = -log(T(k+1)) / ((k+1) * (k+1));
+      c = b - c;
+      s = s + c * a;
+      b = (k + n) * (k - n) * b / ((k + T(0.5f)) * (k + 1));
+   }
+   return s / d;
+}
+
+template <class T>
+T zeta_series_2(unsigned digits)
+{
+   // Series part of zeta at 2:
+   BOOST_MATH_STD_USING
+   int n = digits * 301 * 13 / 10000;
+   T d = pow(3 + sqrt(T(8)), n);
+   d = (d + 1 / d) / 2;
+   T b = -1;
+   T c = -d;
+   T s = 0;
+   for(int k = 0; k < n; ++k)
+   {
+      T a = T(1) / ((k + 1) * (k + 1));
+      c = b - c;
+      s = s + c * a;
+      b = (k + n) * (k - n) * b / ((k + T(0.5f)) * (k + 1));
+   }
+   return s / d;
+}
+
+template <class T>
+inline T zeta_series_lead_2()
+{
+   // lead part at 2:
+   return 2;
+}
+
+template <class T>
+inline T zeta_series_derivative_lead_2()
+{
+   // derivative of lead part at 2:
+   return -2 * boost::math::constants::ln_two<T>();
+}
+
+template <class T>
+inline T zeta_derivative_2(unsigned n)
+{
+   // zeta derivative at 2:
+   return zeta_series_derivative_2<T>(n) * zeta_series_lead_2<T>()
+      + zeta_series_derivative_lead_2<T>() * zeta_series_2<T>(n);
+}
+
+}  // namespace detail
+
+template <class T>
+template<int N>
+inline T constant_glaisher<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+
+   BOOST_MATH_STD_USING
+   typedef policies::policy<policies::digits2<N> > forwarding_policy;
+   int n = N ? (std::min)(N, tools::digits<T>()) : tools::digits<T>();
+   T v = detail::zeta_derivative_2<T>(n);
+   v *= 6;
+   v /= boost::math::constants::pi<T, forwarding_policy>() * boost::math::constants::pi<T, forwarding_policy>();
+   v -= boost::math::constants::euler<T, forwarding_policy>();
+   v -= log(2 * boost::math::constants::pi<T, forwarding_policy>());
+   v /= -12;
+   return exp(v);
+
+ /*
+   // from http://mpmath.googlecode.com/svn/data/glaisher.txt
+     // 20,000 digits of the Glaisher-Kinkelin constant A = exp(1/2 - zeta'(-1))
+     // Computed using A = exp((6 (-zeta'(2))/pi^2 + log 2 pi + gamma)/12)
+  // with Euler-Maclaurin summation for zeta'(2).
+  T g(
+  "1.282427129100622636875342568869791727767688927325001192063740021740406308858826"
+  "46112973649195820237439420646120399000748933157791362775280404159072573861727522"
+  "14334327143439787335067915257366856907876561146686449997784962754518174312394652"
+  "76128213808180219264516851546143919901083573730703504903888123418813674978133050"
+  "93770833682222494115874837348064399978830070125567001286994157705432053927585405"
+  "81731588155481762970384743250467775147374600031616023046613296342991558095879293"
+  "36343887288701988953460725233184702489001091776941712153569193674967261270398013"
+  "52652668868978218897401729375840750167472114895288815996668743164513890306962645"
+  "59870469543740253099606800842447417554061490189444139386196089129682173528798629"
+  "88434220366989900606980888785849587494085307347117090132667567503310523405221054"
+  "14176776156308191919997185237047761312315374135304725819814797451761027540834943"
+  "14384965234139453373065832325673954957601692256427736926358821692159870775858274"
+  "69575162841550648585890834128227556209547002918593263079373376942077522290940187");
+
+  return g;
+  */
+}
+
+template <class T>
+template<int N>
+inline T constant_rayleigh_skewness<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{  // From e_float
+  // 1100 digits of the Rayleigh distribution skewness
+  // Mathematica: N[2 Sqrt[Pi] (Pi - 3)/((4 - Pi)^(3/2)), 1100]
+
+   BOOST_MATH_STD_USING
+   T rs(2 * root_pi<T, policies::policy<policies::digits2<N> > >()
+      * pi_minus_three<T, policies::policy<policies::digits2<N> > >()
+      / pow(four_minus_pi<T, policies::policy<policies::digits2<N> > >(), static_cast<T>(3./2))
+      );
+ //   6.31110657818937138191899351544227779844042203134719497658094585692926819617473725459905027032537306794400047264,
+
+  //"0.6311106578189371381918993515442277798440422031347194976580945856929268196174737254599050270325373067"
+  //"9440004726436754739597525250317640394102954301685809920213808351450851396781817932734836994829371322"
+  //"5797376021347531983451654130317032832308462278373358624120822253764532674177325950686466133508511968"
+  //"2389168716630349407238090652663422922072397393006683401992961569208109477307776249225072042971818671"
+  //"4058887072693437217879039875871765635655476241624825389439481561152126886932506682176611183750503553"
+  //"1218982627032068396407180216351425758181396562859085306247387212297187006230007438534686340210168288"
+  //"8956816965453815849613622117088096547521391672977226658826566757207615552041767516828171274858145957"
+  //"6137539156656005855905288420585194082284972984285863898582313048515484073396332610565441264220790791"
+  //"0194897267890422924599776483890102027823328602965235306539844007677157873140562950510028206251529523"
+  //"7428049693650605954398446899724157486062545281504433364675815915402937209673727753199567661561209251"
+  //"4695589950526053470201635372590001578503476490223746511106018091907936826431407434894024396366284848");  ;
+  return rs;
+}
+
+template <class T>
+template<int N>
+inline T constant_rayleigh_kurtosis_excess<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{ // - (6 Pi^2 - 24 Pi + 16)/((Pi - 4)^2)
+    // Might provide and calculate this using pi_minus_four.
+   BOOST_MATH_STD_USING
+   return - (((static_cast<T>(6) * pi<T, policies::policy<policies::digits2<N> > >()
+        * pi<T, policies::policy<policies::digits2<N> > >())
+   - (static_cast<T>(24) * pi<T, policies::policy<policies::digits2<N> > >()) + static_cast<T>(16) )
+   /
+   ((pi<T, policies::policy<policies::digits2<N> > >() - static_cast<T>(4))
+   * (pi<T, policies::policy<policies::digits2<N> > >() - static_cast<T>(4)))
+   );
+}
+
+template <class T>
+template<int N>
+inline T constant_rayleigh_kurtosis<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{ // 3 - (6 Pi^2 - 24 Pi + 16)/((Pi - 4)^2)
+  // Might provide and calculate this using pi_minus_four.
+   BOOST_MATH_STD_USING
+   return static_cast<T>(3) - (((static_cast<T>(6) * pi<T, policies::policy<policies::digits2<N> > >()
+        * pi<T, policies::policy<policies::digits2<N> > >())
+   - (static_cast<T>(24) * pi<T, policies::policy<policies::digits2<N> > >()) + static_cast<T>(16) )
+   /
+   ((pi<T, policies::policy<policies::digits2<N> > >() - static_cast<T>(4))
+   * (pi<T, policies::policy<policies::digits2<N> > >() - static_cast<T>(4)))
+   );
+}
+
+template <class T>
+template<int N>
+inline T constant_log2_e<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   return 1 / boost::math::constants::ln_two<T>();
+}
+
+template <class T>
+template<int N>
+inline T constant_quarter_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   return boost::math::constants::pi<T>() / 4;
+}
+
+template <class T>
+template<int N>
+inline T constant_one_div_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   return 1 / boost::math::constants::pi<T>();
+}
+
+template <class T>
+template<int N>
+inline T constant_two_div_root_pi<T>::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))
+{
+   return 2 * boost::math::constants::one_div_root_pi<T>();
+}
+
+}
+}
+}
+} // namespaces
+
+#endif // BOOST_MATH_CALCULATE_CONSTANTS_CONSTANTS_INCLUDED
diff --git a/ThirdParty/boost/math/constants/constants.hpp b/ThirdParty/boost/math/constants/constants.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6b57e474632c5f78d4c0906af4e4db09282f8c85
--- /dev/null
+++ b/ThirdParty/boost/math/constants/constants.hpp
@@ -0,0 +1,340 @@
+//  Copyright John Maddock 2005-2006, 2011.
+//  Copyright Paul A. Bristow 2006-2011.
+//  Use, modification and distribution are subject to 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_CONSTANTS_CONSTANTS_INCLUDED
+#define BOOST_MATH_CONSTANTS_CONSTANTS_INCLUDED
+
+#include <boost/math/tools/config.hpp>
+#include <boost/math/tools/cxx03_warn.hpp>
+#include <boost/math/policies/policy.hpp>
+#include <boost/math/tools/precision.hpp>
+#include <boost/math/tools/convert_from_string.hpp>
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4127 4701)
+#endif
+#ifndef BOOST_MATH_NO_LEXICAL_CAST
+#include <boost/lexical_cast.hpp>
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/utility/declval.hpp>
+
+#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128)
+//
+// This is the only way we can avoid
+// warning: non-standard suffix on floating constant [-Wpedantic]
+// when building with -Wall -pedantic.  Neither __extension__
+// nor #pragma diagnostic ignored work :(
+//
+#pragma GCC system_header
+#endif
+
+namespace boost{ namespace math
+{
+  namespace constants
+  {
+    // To permit other calculations at about 100 decimal digits with some UDT,
+    // it is obviously necessary to define constants to this accuracy.
+
+    // However, some compilers do not accept decimal digits strings as long as this.
+    // So the constant is split into two parts, with the 1st containing at least
+    // long double precision, and the 2nd zero if not needed or known.
+    // The 3rd part permits an exponent to be provided if necessary (use zero if none) -
+    // the other two parameters may only contain decimal digits (and sign and decimal point),
+    // and may NOT include an exponent like 1.234E99.
+    // The second digit string is only used if T is a User-Defined Type,
+    // when the constant is converted to a long string literal and lexical_casted to type T.
+    // (This is necessary because you can't use a numeric constant
+    // since even a long double might not have enough digits).
+
+   enum construction_method
+   {
+      construct_from_float = 1,
+      construct_from_double = 2,
+      construct_from_long_double = 3,
+      construct_from_string = 4,
+      construct_from_float128 = 5,
+      // Must be the largest value above:
+      construct_max = construct_from_float128
+   };
+
+   //
+   // Traits class determines how to convert from string based on whether T has a constructor
+   // from const char* or not:
+   //
+   template <int N>
+   struct dummy_size{};
+
+   //
+   // Max number of binary digits in the string representations of our constants:
+   //
+   BOOST_STATIC_CONSTANT(int, max_string_digits = (101 * 1000L) / 301L);
+
+   template <class Real, class Policy>
+   struct construction_traits
+   {
+   private:
+      typedef typename policies::precision<Real, Policy>::type real_precision;
+      typedef typename policies::precision<float, Policy>::type float_precision;
+      typedef typename policies::precision<double, Policy>::type double_precision;
+      typedef typename policies::precision<long double, Policy>::type long_double_precision;
+   public:
+      typedef boost::integral_constant<int,
+         (0 == real_precision::value) ? 0 :
+         boost::is_convertible<float, Real>::value && (real_precision::value <= float_precision::value)? construct_from_float :
+         boost::is_convertible<double, Real>::value && (real_precision::value <= double_precision::value)? construct_from_double :
+         boost::is_convertible<long double, Real>::value && (real_precision::value <= long_double_precision::value)? construct_from_long_double :
+#ifdef BOOST_MATH_USE_FLOAT128
+         boost::is_convertible<BOOST_MATH_FLOAT128_TYPE, Real>::value && (real_precision::value <= 113) ? construct_from_float128 :
+#endif
+         (real_precision::value <= max_string_digits) ? construct_from_string : real_precision::value
+      > type;
+   };
+
+#ifdef BOOST_HAS_THREADS
+#define BOOST_MATH_CONSTANT_THREAD_HELPER(name, prefix) \
+      boost::once_flag f = BOOST_ONCE_INIT;\
+      boost::call_once(f, &BOOST_JOIN(BOOST_JOIN(string_, get_), name)<T>);
+#else
+#define BOOST_MATH_CONSTANT_THREAD_HELPER(name, prefix)
+#endif
+
+   namespace detail{
+
+      template <class Real, class Policy = boost::math::policies::policy<> >
+      struct constant_return
+      {
+         typedef typename construction_traits<Real, Policy>::type construct_type;
+         typedef typename mpl::if_c<
+            (construct_type::value == construct_from_string) || (construct_type::value > construct_max),
+            const Real&, Real>::type type;
+      };
+
+      template <class T, const T& (*F)()>
+      struct constant_initializer
+      {
+         static void force_instantiate()
+         {
+            init.force_instantiate();
+         }
+      private:
+         struct initializer
+         {
+            initializer()
+            {
+               F();
+            }
+            void force_instantiate()const{}
+         };
+         static const initializer init;
+      };
+
+      template <class T, const T& (*F)()>
+      typename constant_initializer<T, F>::initializer const constant_initializer<T, F>::init;
+
+      template <class T, int N, const T& (*F)(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))>
+      struct constant_initializer2
+      {
+         static void force_instantiate()
+         {
+            init.force_instantiate();
+         }
+      private:
+         struct initializer
+         {
+            initializer()
+            {
+               F();
+            }
+            void force_instantiate()const{}
+         };
+         static const initializer init;
+      };
+
+      template <class T, int N, const T& (*F)(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))>
+      typename constant_initializer2<T, N, F>::initializer const constant_initializer2<T, N, F>::init;
+
+   }
+
+#ifdef BOOST_MATH_USE_FLOAT128
+#  define BOOST_MATH_FLOAT128_CONSTANT_OVERLOAD(x) \
+   static inline BOOST_CONSTEXPR T get(const boost::integral_constant<int, construct_from_float128>&) BOOST_NOEXCEPT\
+   { return BOOST_JOIN(x, Q); }
+#else
+#  define BOOST_MATH_FLOAT128_CONSTANT_OVERLOAD(x)
+#endif
+
+#ifdef BOOST_NO_CXX11_THREAD_LOCAL
+#  define BOOST_MATH_PRECOMPUTE_IF_NOT_LOCAL(constant_, name)       constant_initializer<T, & BOOST_JOIN(constant_, name)<T>::get_from_variable_precision>::force_instantiate();
+#else
+#  define BOOST_MATH_PRECOMPUTE_IF_NOT_LOCAL(constant_, name)
+#endif
+
+#define BOOST_DEFINE_MATH_CONSTANT(name, x, y)\
+   namespace detail{\
+   template <class T> struct BOOST_JOIN(constant_, name){\
+   private:\
+   /* The default implementations come next: */ \
+   static inline const T& get_from_string()\
+   {\
+      static const T result(boost::math::tools::convert_from_string<T>(y));\
+      return result;\
+   }\
+   /* This one is for very high precision that is none the less known at compile time: */ \
+   template <int N> static T compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)));\
+   template <int N> static inline const T& get_from_compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((boost::integral_constant<int, N>)))\
+   {\
+      static const T result = compute<N>();\
+      return result;\
+   }\
+   static inline const T& get_from_variable_precision()\
+   {\
+      static BOOST_MATH_THREAD_LOCAL int digits = 0;\
+      static BOOST_MATH_THREAD_LOCAL T value;\
+      int current_digits = boost::math::tools::digits<T>();\
+      if(digits != current_digits)\
+      {\
+         value = current_digits > max_string_digits ? compute<0>() : T(boost::math::tools::convert_from_string<T>(y));\
+         digits = current_digits; \
+      }\
+      return value;\
+   }\
+   /* public getters come next */\
+   public:\
+   static inline const T& get(const boost::integral_constant<int, construct_from_string>&)\
+   {\
+      constant_initializer<T, & BOOST_JOIN(constant_, name)<T>::get_from_string >::force_instantiate();\
+      return get_from_string();\
+   }\
+   static inline BOOST_CONSTEXPR T get(const boost::integral_constant<int, construct_from_float>) BOOST_NOEXCEPT\
+   { return BOOST_JOIN(x, F); }\
+   static inline BOOST_CONSTEXPR T get(const boost::integral_constant<int, construct_from_double>&) BOOST_NOEXCEPT\
+   { return x; }\
+   static inline BOOST_CONSTEXPR T get(const boost::integral_constant<int, construct_from_long_double>&) BOOST_NOEXCEPT\
+   { return BOOST_JOIN(x, L); }\
+   BOOST_MATH_FLOAT128_CONSTANT_OVERLOAD(x) \
+   template <int N> static inline const T& get(const boost::integral_constant<int, N>&)\
+   {\
+      constant_initializer2<T, N, & BOOST_JOIN(constant_, name)<T>::template get_from_compute<N> >::force_instantiate();\
+      return get_from_compute<N>(); \
+   }\
+   /* This one is for true arbitrary precision, which may well vary at runtime: */ \
+   static inline T get(const boost::integral_constant<int, 0>&)\
+   {\
+      BOOST_MATH_PRECOMPUTE_IF_NOT_LOCAL(constant_, name)\
+      return get_from_variable_precision(); }\
+   }; /* end of struct */\
+   } /* namespace detail */ \
+   \
+   \
+   /* The actual forwarding function: */ \
+   template <class T, class Policy> inline BOOST_CONSTEXPR typename detail::constant_return<T, Policy>::type name(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(Policy)) BOOST_MATH_NOEXCEPT(T)\
+   { return detail:: BOOST_JOIN(constant_, name)<T>::get(typename construction_traits<T, Policy>::type()); }\
+   template <class T> inline BOOST_CONSTEXPR typename detail::constant_return<T>::type name(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) BOOST_MATH_NOEXCEPT(T)\
+   { return name<T, boost::math::policies::policy<> >(); }\
+   \
+   \
+   /* Now the namespace specific versions: */ \
+   } namespace float_constants{ BOOST_STATIC_CONSTEXPR float name = BOOST_JOIN(x, F); }\
+   namespace double_constants{ BOOST_STATIC_CONSTEXPR double name = x; } \
+   namespace long_double_constants{ BOOST_STATIC_CONSTEXPR long double name = BOOST_JOIN(x, L); }\
+   namespace constants{
+
+  BOOST_DEFINE_MATH_CONSTANT(half, 5.000000000000000000000000000000000000e-01, "5.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-01")
+  BOOST_DEFINE_MATH_CONSTANT(third, 3.333333333333333333333333333333333333e-01, "3.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333e-01")
+  BOOST_DEFINE_MATH_CONSTANT(twothirds, 6.666666666666666666666666666666666666e-01, "6.66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667e-01")
+  BOOST_DEFINE_MATH_CONSTANT(two_thirds, 6.666666666666666666666666666666666666e-01, "6.66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667e-01")
+  BOOST_DEFINE_MATH_CONSTANT(sixth, 1.666666666666666666666666666666666666e-01, "1.66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667e-01")
+  BOOST_DEFINE_MATH_CONSTANT(three_quarters, 7.500000000000000000000000000000000000e-01, "7.50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-01")
+  BOOST_DEFINE_MATH_CONSTANT(root_two, 1.414213562373095048801688724209698078e+00, "1.41421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157273501384623e+00")
+  BOOST_DEFINE_MATH_CONSTANT(root_three, 1.732050807568877293527446341505872366e+00, "1.73205080756887729352744634150587236694280525381038062805580697945193301690880003708114618675724857567562614142e+00")
+  BOOST_DEFINE_MATH_CONSTANT(half_root_two, 7.071067811865475244008443621048490392e-01, "7.07106781186547524400844362104849039284835937688474036588339868995366239231053519425193767163820786367506923115e-01")
+  BOOST_DEFINE_MATH_CONSTANT(ln_two, 6.931471805599453094172321214581765680e-01, "6.93147180559945309417232121458176568075500134360255254120680009493393621969694715605863326996418687542001481021e-01")
+  BOOST_DEFINE_MATH_CONSTANT(ln_ln_two, -3.665129205816643270124391582326694694e-01, "-3.66512920581664327012439158232669469454263447837105263053677713670561615319352738549455822856698908358302523045e-01")
+  BOOST_DEFINE_MATH_CONSTANT(root_ln_four, 1.177410022515474691011569326459699637e+00, "1.17741002251547469101156932645969963774738568938582053852252575650002658854698492680841813836877081106747157858e+00")
+  BOOST_DEFINE_MATH_CONSTANT(one_div_root_two, 7.071067811865475244008443621048490392e-01, "7.07106781186547524400844362104849039284835937688474036588339868995366239231053519425193767163820786367506923115e-01")
+  BOOST_DEFINE_MATH_CONSTANT(pi, 3.141592653589793238462643383279502884e+00, "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651e+00")
+  BOOST_DEFINE_MATH_CONSTANT(half_pi, 1.570796326794896619231321691639751442e+00, "1.57079632679489661923132169163975144209858469968755291048747229615390820314310449931401741267105853399107404326e+00")
+  BOOST_DEFINE_MATH_CONSTANT(third_pi, 1.047197551196597746154214461093167628e+00, "1.04719755119659774615421446109316762806572313312503527365831486410260546876206966620934494178070568932738269550e+00")
+  BOOST_DEFINE_MATH_CONSTANT(sixth_pi, 5.235987755982988730771072305465838140e-01, "5.23598775598298873077107230546583814032861566562517636829157432051302734381034833104672470890352844663691347752e-01")
+  BOOST_DEFINE_MATH_CONSTANT(two_pi, 6.283185307179586476925286766559005768e+00, "6.28318530717958647692528676655900576839433879875021164194988918461563281257241799725606965068423413596429617303e+00")
+  BOOST_DEFINE_MATH_CONSTANT(two_thirds_pi, 2.094395102393195492308428922186335256e+00, "2.09439510239319549230842892218633525613144626625007054731662972820521093752413933241868988356141137865476539101e+00")
+  BOOST_DEFINE_MATH_CONSTANT(three_quarters_pi, 2.356194490192344928846982537459627163e+00, "2.35619449019234492884698253745962716314787704953132936573120844423086230471465674897102611900658780098661106488e+00")
+  BOOST_DEFINE_MATH_CONSTANT(four_thirds_pi, 4.188790204786390984616857844372670512e+00, "4.18879020478639098461685784437267051226289253250014109463325945641042187504827866483737976712282275730953078202e+00")
+  BOOST_DEFINE_MATH_CONSTANT(one_div_two_pi, 1.591549430918953357688837633725143620e-01, "1.59154943091895335768883763372514362034459645740456448747667344058896797634226535090113802766253085956072842727e-01")
+  BOOST_DEFINE_MATH_CONSTANT(one_div_root_two_pi, 3.989422804014326779399460599343818684e-01, "3.98942280401432677939946059934381868475858631164934657665925829670657925899301838501252333907306936430302558863e-01")
+  BOOST_DEFINE_MATH_CONSTANT(root_pi, 1.772453850905516027298167483341145182e+00, "1.77245385090551602729816748334114518279754945612238712821380778985291128459103218137495065673854466541622682362e+00")
+  BOOST_DEFINE_MATH_CONSTANT(root_half_pi, 1.253314137315500251207882642405522626e+00, "1.25331413731550025120788264240552262650349337030496915831496178817114682730392098747329791918902863305800498633e+00")
+  BOOST_DEFINE_MATH_CONSTANT(root_two_pi, 2.506628274631000502415765284811045253e+00, "2.50662827463100050241576528481104525300698674060993831662992357634229365460784197494659583837805726611600997267e+00")
+  BOOST_DEFINE_MATH_CONSTANT(log_root_two_pi, 9.189385332046727417803297364056176398e-01, "9.18938533204672741780329736405617639861397473637783412817151540482765695927260397694743298635954197622005646625e-01")
+  BOOST_DEFINE_MATH_CONSTANT(one_div_root_pi, 5.641895835477562869480794515607725858e-01, "5.64189583547756286948079451560772585844050629328998856844085721710642468441493414486743660202107363443028347906e-01")
+  BOOST_DEFINE_MATH_CONSTANT(root_one_div_pi, 5.641895835477562869480794515607725858e-01, "5.64189583547756286948079451560772585844050629328998856844085721710642468441493414486743660202107363443028347906e-01")
+  BOOST_DEFINE_MATH_CONSTANT(pi_minus_three, 1.415926535897932384626433832795028841e-01, "1.41592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513e-01")
+  BOOST_DEFINE_MATH_CONSTANT(four_minus_pi, 8.584073464102067615373566167204971158e-01, "8.58407346410206761537356616720497115802830600624894179025055407692183593713791001371965174657882932017851913487e-01")
+  //BOOST_DEFINE_MATH_CONSTANT(pow23_four_minus_pi, 7.953167673715975443483953350568065807e-01, "7.95316767371597544348395335056806580727639173327713205445302234388856268267518187590758006888600828436839800178e-01")
+  BOOST_DEFINE_MATH_CONSTANT(pi_pow_e, 2.245915771836104547342715220454373502e+01, "2.24591577183610454734271522045437350275893151339966922492030025540669260403991179123185197527271430315314500731e+01")
+  BOOST_DEFINE_MATH_CONSTANT(pi_sqr, 9.869604401089358618834490999876151135e+00, "9.86960440108935861883449099987615113531369940724079062641334937622004482241920524300177340371855223182402591377e+00")
+  BOOST_DEFINE_MATH_CONSTANT(pi_sqr_div_six, 1.644934066848226436472415166646025189e+00, "1.64493406684822643647241516664602518921894990120679843773555822937000747040320087383362890061975870530400431896e+00")
+  BOOST_DEFINE_MATH_CONSTANT(pi_cubed, 3.100627668029982017547631506710139520e+01, "3.10062766802998201754763150671013952022252885658851076941445381038063949174657060375667010326028861930301219616e+01")
+  BOOST_DEFINE_MATH_CONSTANT(cbrt_pi, 1.464591887561523263020142527263790391e+00, "1.46459188756152326302014252726379039173859685562793717435725593713839364979828626614568206782035382089750397002e+00")
+  BOOST_DEFINE_MATH_CONSTANT(one_div_cbrt_pi, 6.827840632552956814670208331581645981e-01, "6.82784063255295681467020833158164598108367515632448804042681583118899226433403918237673501922595519865685577274e-01")
+  BOOST_DEFINE_MATH_CONSTANT(log2_e, 1.44269504088896340735992468100189213742664595415298, "1.44269504088896340735992468100189213742664595415298593413544940693110921918118507988552662289350634449699751830965e+00")
+  BOOST_DEFINE_MATH_CONSTANT(e, 2.718281828459045235360287471352662497e+00, "2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193e+00")
+  BOOST_DEFINE_MATH_CONSTANT(exp_minus_half, 6.065306597126334236037995349911804534e-01, "6.06530659712633423603799534991180453441918135487186955682892158735056519413748423998647611507989456026423789794e-01")
+  BOOST_DEFINE_MATH_CONSTANT(exp_minus_one, 3.678794411714423215955237701614608674e-01, "3.67879441171442321595523770161460867445811131031767834507836801697461495744899803357147274345919643746627325277e-01")
+  BOOST_DEFINE_MATH_CONSTANT(e_pow_pi, 2.314069263277926900572908636794854738e+01, "2.31406926327792690057290863679485473802661062426002119934450464095243423506904527835169719970675492196759527048e+01")
+  BOOST_DEFINE_MATH_CONSTANT(root_e, 1.648721270700128146848650787814163571e+00, "1.64872127070012814684865078781416357165377610071014801157507931164066102119421560863277652005636664300286663776e+00")
+  BOOST_DEFINE_MATH_CONSTANT(log10_e, 4.342944819032518276511289189166050822e-01, "4.34294481903251827651128918916605082294397005803666566114453783165864649208870774729224949338431748318706106745e-01")
+  BOOST_DEFINE_MATH_CONSTANT(one_div_log10_e, 2.302585092994045684017991454684364207e+00, "2.30258509299404568401799145468436420760110148862877297603332790096757260967735248023599720508959829834196778404e+00")
+  BOOST_DEFINE_MATH_CONSTANT(ln_ten, 2.302585092994045684017991454684364207e+00, "2.30258509299404568401799145468436420760110148862877297603332790096757260967735248023599720508959829834196778404e+00")
+  BOOST_DEFINE_MATH_CONSTANT(degree, 1.745329251994329576923690768488612713e-02, "1.74532925199432957692369076848861271344287188854172545609719144017100911460344944368224156963450948221230449251e-02")
+  BOOST_DEFINE_MATH_CONSTANT(radian, 5.729577951308232087679815481410517033e+01, "5.72957795130823208767981548141051703324054724665643215491602438612028471483215526324409689958511109441862233816e+01")
+  BOOST_DEFINE_MATH_CONSTANT(sin_one, 8.414709848078965066525023216302989996e-01, "8.41470984807896506652502321630298999622563060798371065672751709991910404391239668948639743543052695854349037908e-01")
+  BOOST_DEFINE_MATH_CONSTANT(cos_one, 5.403023058681397174009366074429766037e-01, "5.40302305868139717400936607442976603732310420617922227670097255381100394774471764517951856087183089343571731160e-01")
+  BOOST_DEFINE_MATH_CONSTANT(sinh_one, 1.175201193643801456882381850595600815e+00, "1.17520119364380145688238185059560081515571798133409587022956541301330756730432389560711745208962339184041953333e+00")
+  BOOST_DEFINE_MATH_CONSTANT(cosh_one, 1.543080634815243778477905620757061682e+00, "1.54308063481524377847790562075706168260152911236586370473740221471076906304922369896426472643554303558704685860e+00")
+  BOOST_DEFINE_MATH_CONSTANT(phi, 1.618033988749894848204586834365638117e+00, "1.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748475408808e+00")
+  BOOST_DEFINE_MATH_CONSTANT(ln_phi, 4.812118250596034474977589134243684231e-01, "4.81211825059603447497758913424368423135184334385660519661018168840163867608221774412009429122723474997231839958e-01")
+  BOOST_DEFINE_MATH_CONSTANT(one_div_ln_phi, 2.078086921235027537601322606117795767e+00, "2.07808692123502753760132260611779576774219226778328348027813992191974386928553540901445615414453604821933918634e+00")
+  BOOST_DEFINE_MATH_CONSTANT(euler, 5.772156649015328606065120900824024310e-01, "5.77215664901532860606512090082402431042159335939923598805767234884867726777664670936947063291746749514631447250e-01")
+  BOOST_DEFINE_MATH_CONSTANT(one_div_euler, 1.732454714600633473583025315860829681e+00, "1.73245471460063347358302531586082968115577655226680502204843613287065531408655243008832840219409928068072365714e+00")
+  BOOST_DEFINE_MATH_CONSTANT(euler_sqr, 3.331779238077186743183761363552442266e-01, "3.33177923807718674318376136355244226659417140249629743150833338002265793695756669661263268631715977303039565603e-01")
+  BOOST_DEFINE_MATH_CONSTANT(zeta_two, 1.644934066848226436472415166646025189e+00, "1.64493406684822643647241516664602518921894990120679843773555822937000747040320087383362890061975870530400431896e+00")
+  BOOST_DEFINE_MATH_CONSTANT(zeta_three, 1.202056903159594285399738161511449990e+00, "1.20205690315959428539973816151144999076498629234049888179227155534183820578631309018645587360933525814619915780e+00")
+  BOOST_DEFINE_MATH_CONSTANT(catalan, 9.159655941772190150546035149323841107e-01, "9.15965594177219015054603514932384110774149374281672134266498119621763019776254769479356512926115106248574422619e-01")
+  BOOST_DEFINE_MATH_CONSTANT(glaisher, 1.282427129100622636875342568869791727e+00, "1.28242712910062263687534256886979172776768892732500119206374002174040630885882646112973649195820237439420646120e+00")
+  BOOST_DEFINE_MATH_CONSTANT(khinchin, 2.685452001065306445309714835481795693e+00, "2.68545200106530644530971483548179569382038229399446295305115234555721885953715200280114117493184769799515346591e+00")
+  BOOST_DEFINE_MATH_CONSTANT(extreme_value_skewness, 1.139547099404648657492793019389846112e+00, "1.13954709940464865749279301938984611208759979583655182472165571008524800770607068570718754688693851501894272049e+00")
+  BOOST_DEFINE_MATH_CONSTANT(rayleigh_skewness, 6.311106578189371381918993515442277798e-01, "6.31110657818937138191899351544227779844042203134719497658094585692926819617473725459905027032537306794400047264e-01")
+  BOOST_DEFINE_MATH_CONSTANT(rayleigh_kurtosis, 3.245089300687638062848660410619754415e+00, "3.24508930068763806284866041061975441541706673178920936177133764493367904540874159051490619368679348977426462633e+00")
+  BOOST_DEFINE_MATH_CONSTANT(rayleigh_kurtosis_excess, 2.450893006876380628486604106197544154e-01, "2.45089300687638062848660410619754415417066731789209361771337644933679045408741590514906193686793489774264626328e-01")
+
+  BOOST_DEFINE_MATH_CONSTANT(two_div_pi, 6.366197723675813430755350534900574481e-01, "6.36619772367581343075535053490057448137838582961825794990669376235587190536906140360455211065012343824291370907e-01")
+  BOOST_DEFINE_MATH_CONSTANT(root_two_div_pi, 7.978845608028653558798921198687637369e-01, "7.97884560802865355879892119868763736951717262329869315331851659341315851798603677002504667814613872860605117725e-01")
+  BOOST_DEFINE_MATH_CONSTANT(quarter_pi, 0.785398163397448309615660845819875721049292, "0.785398163397448309615660845819875721049292349843776455243736148076954101571552249657008706335529266995537021628320576661773")
+  BOOST_DEFINE_MATH_CONSTANT(one_div_pi, 0.3183098861837906715377675267450287240689192, "0.31830988618379067153776752674502872406891929148091289749533468811779359526845307018022760553250617191214568545351")
+  BOOST_DEFINE_MATH_CONSTANT(two_div_root_pi, 1.12837916709551257389615890312154517168810125, "1.12837916709551257389615890312154517168810125865799771368817144342128493688298682897348732040421472688605669581272")
+
+
+} // namespace constants
+} // namespace math
+} // namespace boost
+
+//
+// We deliberately include this *after* all the declarations above,
+// that way the calculation routines can call on other constants above:
+//
+#include <boost/math/constants/calculate_constants.hpp>
+
+#endif // BOOST_MATH_CONSTANTS_CONSTANTS_INCLUDED
+
+
diff --git a/ThirdParty/boost/math/policies/error_handling.hpp b/ThirdParty/boost/math/policies/error_handling.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..124337ee879ac2ff04894d9236467b0223e9e372
--- /dev/null
+++ b/ThirdParty/boost/math/policies/error_handling.hpp
@@ -0,0 +1,847 @@
+//  Copyright John Maddock 2007.
+//  Copyright Paul A. Bristow 2007.
+
+//  Use, modification and distribution are subject to 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_POLICY_ERROR_HANDLING_HPP
+#define BOOST_MATH_POLICY_ERROR_HANDLING_HPP
+
+#include <stdexcept>
+#include <iomanip>
+#include <string>
+#include <cstring>
+#include <typeinfo>
+#include <cerrno>
+#include <boost/config/no_tr1/complex.hpp>
+#include <boost/config/no_tr1/cmath.hpp>
+#include <stdexcept>
+#include <boost/math/tools/config.hpp>
+#include <boost/math/policies/policy.hpp>
+#include <boost/math/tools/precision.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/cstdint.hpp>
+#ifdef BOOST_MSVC
+#  pragma warning(push) // Quiet warnings in boost/format.hpp
+#  pragma warning(disable: 4996) // _SCL_SECURE_NO_DEPRECATE
+#  pragma warning(disable: 4512) // assignment operator could not be generated.
+#  pragma warning(disable: 4127) // conditional expression is constant
+// And warnings in error handling:
+#  pragma warning(disable: 4702) // unreachable code.
+// Note that this only occurs when the compiler can deduce code is unreachable,
+// for example when policy macros are used to ignore errors rather than throw.
+#endif
+#include <sstream>
+
+namespace boost{ namespace math{
+
+class evaluation_error : public std::runtime_error
+{
+public:
+   evaluation_error(const std::string& s) : std::runtime_error(s){}
+};
+
+class rounding_error : public std::runtime_error
+{
+public:
+   rounding_error(const std::string& s) : std::runtime_error(s){}
+};
+
+namespace policies{
+//
+// Forward declarations of user error handlers,
+// it's up to the user to provide the definition of these:
+//
+template <class T>
+T user_domain_error(const char* function, const char* message, const T& val);
+template <class T>
+T user_pole_error(const char* function, const char* message, const T& val);
+template <class T>
+T user_overflow_error(const char* function, const char* message, const T& val);
+template <class T>
+T user_underflow_error(const char* function, const char* message, const T& val);
+template <class T>
+T user_denorm_error(const char* function, const char* message, const T& val);
+template <class T>
+T user_evaluation_error(const char* function, const char* message, const T& val);
+template <class T, class TargetType>
+T user_rounding_error(const char* function, const char* message, const T& val, const TargetType& t);
+template <class T>
+T user_indeterminate_result_error(const char* function, const char* message, const T& val);
+
+namespace detail
+{
+
+template <class T>
+std::string prec_format(const T& val)
+{
+   typedef typename boost::math::policies::precision<T, boost::math::policies::policy<> >::type prec_type;
+   std::stringstream ss;
+   if(prec_type::value)
+   {
+      int prec = 2 + (prec_type::value * 30103UL) / 100000UL;
+      ss << std::setprecision(prec);
+   }
+   ss << val;
+   return ss.str();
+}
+
+inline void replace_all_in_string(std::string& result, const char* what, const char* with)
+{
+   std::string::size_type pos = 0;
+   std::string::size_type slen = std::strlen(what);
+   std::string::size_type rlen = std::strlen(with);
+   while((pos = result.find(what, pos)) != std::string::npos)
+   {
+      result.replace(pos, slen, with);
+      pos += rlen;
+   }
+}
+
+template <class T>
+inline const char* name_of()
+{
+#ifndef BOOST_NO_RTTI
+   return typeid(T).name();
+#else
+   return "unknown";
+#endif
+}
+template <> inline const char* name_of<float>(){ return "float"; }
+template <> inline const char* name_of<double>(){ return "double"; }
+template <> inline const char* name_of<long double>(){ return "long double"; }
+
+#ifdef BOOST_MATH_USE_FLOAT128
+template <>
+inline const char* name_of<BOOST_MATH_FLOAT128_TYPE>()
+{
+   return "__float128";
+}
+#endif
+
+template <class E, class T>
+void raise_error(const char* pfunction, const char* message)
+{
+  if(pfunction == 0)
+     pfunction = "Unknown function operating on type %1%";
+  if(message == 0)
+     message = "Cause unknown";
+
+  std::string function(pfunction);
+  std::string msg("Error in function ");
+#ifndef BOOST_NO_RTTI
+  replace_all_in_string(function, "%1%", boost::math::policies::detail::name_of<T>());
+#else
+  replace_all_in_string(function, "%1%", "Unknown");
+#endif
+  msg += function;
+  msg += ": ";
+  msg += message;
+
+  E e(msg);
+  boost::throw_exception(e);
+}
+
+template <class E, class T>
+void raise_error(const char* pfunction, const char* pmessage, const T& val)
+{
+  if(pfunction == 0)
+     pfunction = "Unknown function operating on type %1%";
+  if(pmessage == 0)
+     pmessage = "Cause unknown: error caused by bad argument with value %1%";
+
+  std::string function(pfunction);
+  std::string message(pmessage);
+  std::string msg("Error in function ");
+#ifndef BOOST_NO_RTTI
+  replace_all_in_string(function, "%1%", boost::math::policies::detail::name_of<T>());
+#else
+  replace_all_in_string(function, "%1%", "Unknown");
+#endif
+  msg += function;
+  msg += ": ";
+
+  std::string sval = prec_format(val);
+  replace_all_in_string(message, "%1%", sval.c_str());
+  msg += message;
+
+  E e(msg);
+  boost::throw_exception(e);
+}
+
+template <class T>
+inline T raise_domain_error(
+           const char* function,
+           const char* message,
+           const T& val,
+           const ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>&)
+{
+   raise_error<std::domain_error, T>(function, message, val);
+   // we never get here:
+   return std::numeric_limits<T>::quiet_NaN();
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T raise_domain_error(
+           const char* ,
+           const char* ,
+           const T& ,
+           const ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   // This may or may not do the right thing, but the user asked for the error
+   // to be ignored so here we go anyway:
+   return std::numeric_limits<T>::quiet_NaN();
+}
+
+template <class T>
+inline T raise_domain_error(
+           const char* ,
+           const char* ,
+           const T& ,
+           const ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   errno = EDOM;
+   // This may or may not do the right thing, but the user asked for the error
+   // to be silent so here we go anyway:
+   return std::numeric_limits<T>::quiet_NaN();
+}
+
+template <class T>
+inline T raise_domain_error(
+           const char* function,
+           const char* message,
+           const T& val,
+           const  ::boost::math::policies::domain_error< ::boost::math::policies::user_error>&)
+{
+   return user_domain_error(function, message, val);
+}
+
+template <class T>
+inline T raise_pole_error(
+           const char* function,
+           const char* message,
+           const T& val,
+           const  ::boost::math::policies::pole_error< ::boost::math::policies::throw_on_error>&)
+{
+   return boost::math::policies::detail::raise_domain_error(function, message, val,  ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>());
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T raise_pole_error(
+           const char* function,
+           const char* message,
+           const T& val,
+           const  ::boost::math::policies::pole_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   return  ::boost::math::policies::detail::raise_domain_error(function, message, val,  ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>());
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T raise_pole_error(
+           const char* function,
+           const char* message,
+           const T& val,
+           const  ::boost::math::policies::pole_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   return  ::boost::math::policies::detail::raise_domain_error(function, message, val,  ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>());
+}
+
+template <class T>
+inline T raise_pole_error(
+           const char* function,
+           const char* message,
+           const T& val,
+           const  ::boost::math::policies::pole_error< ::boost::math::policies::user_error>&)
+{
+   return user_pole_error(function, message, val);
+}
+
+
+template <class T>
+inline T raise_overflow_error(
+           const char* function,
+           const char* message,
+           const  ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&)
+{
+   raise_error<std::overflow_error, T>(function, message ? message : "numeric overflow");
+   // We should never get here:
+   return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
+}
+
+template <class T>
+inline T raise_overflow_error(
+           const char* function,
+           const char* message,
+           const T& val,
+           const ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&)
+{
+   raise_error<std::overflow_error, T>(function, message ? message : "numeric overflow", val);
+   // We should never get here:
+   return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T raise_overflow_error(
+           const char* ,
+           const char* ,
+           const  ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   // This may or may not do the right thing, but the user asked for the error
+   // to be ignored so here we go anyway:
+   return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T raise_overflow_error(
+           const char* ,
+           const char* ,
+           const T&,
+           const  ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   // This may or may not do the right thing, but the user asked for the error
+   // to be ignored so here we go anyway:
+   return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
+}
+
+template <class T>
+inline T raise_overflow_error(
+           const char* ,
+           const char* ,
+           const  ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   errno = ERANGE;
+   // This may or may not do the right thing, but the user asked for the error
+   // to be silent so here we go anyway:
+   return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
+}
+
+template <class T>
+inline T raise_overflow_error(
+           const char* ,
+           const char* ,
+           const T&,
+           const  ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   errno = ERANGE;
+   // This may or may not do the right thing, but the user asked for the error
+   // to be silent so here we go anyway:
+   return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : boost::math::tools::max_value<T>();
+}
+
+template <class T>
+inline T raise_overflow_error(
+           const char* function,
+           const char* message,
+           const  ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&)
+{
+   return user_overflow_error(function, message, std::numeric_limits<T>::infinity());
+}
+
+template <class T>
+inline T raise_overflow_error(
+           const char* function,
+           const char* message,
+           const T& val,
+           const  ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&)
+{
+   std::string m(message ? message : "");
+   std::string sval = prec_format(val);
+   replace_all_in_string(m, "%1%", sval.c_str());
+
+   return user_overflow_error(function, m.c_str(), std::numeric_limits<T>::infinity());
+}
+
+template <class T>
+inline T raise_underflow_error(
+           const char* function,
+           const char* message,
+           const  ::boost::math::policies::underflow_error< ::boost::math::policies::throw_on_error>&)
+{
+   raise_error<std::underflow_error, T>(function, message ? message : "numeric underflow");
+   // We should never get here:
+   return 0;
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T raise_underflow_error(
+           const char* ,
+           const char* ,
+           const  ::boost::math::policies::underflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   // This may or may not do the right thing, but the user asked for the error
+   // to be ignored so here we go anyway:
+   return T(0);
+}
+
+template <class T>
+inline T raise_underflow_error(
+           const char* /* function */,
+           const char* /* message */,
+           const  ::boost::math::policies::underflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   errno = ERANGE;
+   // This may or may not do the right thing, but the user asked for the error
+   // to be silent so here we go anyway:
+   return T(0);
+}
+
+template <class T>
+inline T raise_underflow_error(
+           const char* function,
+           const char* message,
+           const  ::boost::math::policies::underflow_error< ::boost::math::policies::user_error>&)
+{
+   return user_underflow_error(function, message, T(0));
+}
+
+template <class T>
+inline T raise_denorm_error(
+           const char* function,
+           const char* message,
+           const T& /* val */,
+           const  ::boost::math::policies::denorm_error< ::boost::math::policies::throw_on_error>&)
+{
+   raise_error<std::underflow_error, T>(function, message ? message : "denormalised result");
+   // we never get here:
+   return T(0);
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T raise_denorm_error(
+           const char* ,
+           const char* ,
+           const T&  val,
+           const  ::boost::math::policies::denorm_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   // This may or may not do the right thing, but the user asked for the error
+   // to be ignored so here we go anyway:
+   return val;
+}
+
+template <class T>
+inline T raise_denorm_error(
+           const char* ,
+           const char* ,
+           const T& val,
+           const  ::boost::math::policies::denorm_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   errno = ERANGE;
+   // This may or may not do the right thing, but the user asked for the error
+   // to be silent so here we go anyway:
+   return val;
+}
+
+template <class T>
+inline T raise_denorm_error(
+           const char* function,
+           const char* message,
+           const T& val,
+           const  ::boost::math::policies::denorm_error< ::boost::math::policies::user_error>&)
+{
+   return user_denorm_error(function, message, val);
+}
+
+template <class T>
+inline T raise_evaluation_error(
+           const char* function,
+           const char* message,
+           const T& val,
+           const  ::boost::math::policies::evaluation_error< ::boost::math::policies::throw_on_error>&)
+{
+   raise_error<boost::math::evaluation_error, T>(function, message, val);
+   // we never get here:
+   return T(0);
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T raise_evaluation_error(
+           const char* ,
+           const char* ,
+           const T& val,
+           const  ::boost::math::policies::evaluation_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   // This may or may not do the right thing, but the user asked for the error
+   // to be ignored so here we go anyway:
+   return val;
+}
+
+template <class T>
+inline T raise_evaluation_error(
+           const char* ,
+           const char* ,
+           const T& val,
+           const  ::boost::math::policies::evaluation_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   errno = EDOM;
+   // This may or may not do the right thing, but the user asked for the error
+   // to be silent so here we go anyway:
+   return val;
+}
+
+template <class T>
+inline T raise_evaluation_error(
+           const char* function,
+           const char* message,
+           const T& val,
+           const  ::boost::math::policies::evaluation_error< ::boost::math::policies::user_error>&)
+{
+   return user_evaluation_error(function, message, val);
+}
+
+template <class T, class TargetType>
+inline TargetType raise_rounding_error(
+           const char* function,
+           const char* message,
+           const T& val,
+           const TargetType&,
+           const  ::boost::math::policies::rounding_error< ::boost::math::policies::throw_on_error>&)
+{
+   raise_error<boost::math::rounding_error, T>(function, message, val);
+   // we never get here:
+   return TargetType(0);
+}
+
+template <class T, class TargetType>
+inline BOOST_MATH_CONSTEXPR TargetType raise_rounding_error(
+           const char* ,
+           const char* ,
+           const T& val,
+           const TargetType&,
+           const  ::boost::math::policies::rounding_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   // This may or may not do the right thing, but the user asked for the error
+   // to be ignored so here we go anyway:
+   BOOST_STATIC_ASSERT(std::numeric_limits<TargetType>::is_specialized);
+   return  val > 0 ? (std::numeric_limits<TargetType>::max)() : (std::numeric_limits<TargetType>::is_integer ? (std::numeric_limits<TargetType>::min)() : -(std::numeric_limits<TargetType>::max)());
+}
+
+template <class T, class TargetType>
+inline TargetType raise_rounding_error(
+           const char* ,
+           const char* ,
+           const T& val,
+           const TargetType&,
+           const  ::boost::math::policies::rounding_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   errno = ERANGE;
+   // This may or may not do the right thing, but the user asked for the error
+   // to be silent so here we go anyway:
+   BOOST_STATIC_ASSERT(std::numeric_limits<TargetType>::is_specialized);
+   return  val > 0 ? (std::numeric_limits<TargetType>::max)() : (std::numeric_limits<TargetType>::is_integer ? (std::numeric_limits<TargetType>::min)() : -(std::numeric_limits<TargetType>::max)());
+}
+
+template <class T>
+inline T raise_rounding_error(
+           const char* ,
+           const char* ,
+           const T& val,
+           const T&,
+           const  ::boost::math::policies::rounding_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   errno = ERANGE;
+   // This may or may not do the right thing, but the user asked for the error
+   // to be silent so here we go anyway:
+   return  val > 0 ? boost::math::tools::max_value<T>() : -boost::math::tools::max_value<T>();
+}
+
+template <class T, class TargetType>
+inline TargetType raise_rounding_error(
+           const char* function,
+           const char* message,
+           const T& val,
+           const TargetType& t,
+           const  ::boost::math::policies::rounding_error< ::boost::math::policies::user_error>&)
+{
+   return user_rounding_error(function, message, val, t);
+}
+
+template <class T, class R>
+inline T raise_indeterminate_result_error(
+           const char* function,
+           const char* message,
+           const T& val,
+           const R& ,
+           const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::throw_on_error>&)
+{
+   raise_error<std::domain_error, T>(function, message, val);
+   // we never get here:
+   return std::numeric_limits<T>::quiet_NaN();
+}
+
+template <class T, class R>
+inline BOOST_MATH_CONSTEXPR T raise_indeterminate_result_error(
+           const char* ,
+           const char* ,
+           const T& ,
+           const R& result,
+           const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T)
+{
+   // This may or may not do the right thing, but the user asked for the error
+   // to be ignored so here we go anyway:
+   return result;
+}
+
+template <class T, class R>
+inline T raise_indeterminate_result_error(
+           const char* ,
+           const char* ,
+           const T& ,
+           const R& result,
+           const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::errno_on_error>&)
+{
+   errno = EDOM;
+   // This may or may not do the right thing, but the user asked for the error
+   // to be silent so here we go anyway:
+   return result;
+}
+
+template <class T, class R>
+inline T raise_indeterminate_result_error(
+           const char* function,
+           const char* message,
+           const T& val,
+           const R& ,
+           const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::user_error>&)
+{
+   return user_indeterminate_result_error(function, message, val);
+}
+
+}  // namespace detail
+
+template <class T, class Policy>
+inline BOOST_MATH_CONSTEXPR T raise_domain_error(const char* function, const char* message, const T& val, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
+{
+   typedef typename Policy::domain_error_type policy_type;
+   return detail::raise_domain_error(
+      function, message ? message : "Domain Error evaluating function at %1%",
+      val, policy_type());
+}
+
+template <class T, class Policy>
+inline BOOST_MATH_CONSTEXPR T raise_pole_error(const char* function, const char* message, const T& val, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
+{
+   typedef typename Policy::pole_error_type policy_type;
+   return detail::raise_pole_error(
+      function, message ? message : "Evaluation of function at pole %1%",
+      val, policy_type());
+}
+
+template <class T, class Policy>
+inline BOOST_MATH_CONSTEXPR T raise_overflow_error(const char* function, const char* message, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
+{
+   typedef typename Policy::overflow_error_type policy_type;
+   return detail::raise_overflow_error<T>(
+      function, message ? message : "Overflow Error",
+      policy_type());
+}
+
+template <class T, class Policy>
+inline BOOST_MATH_CONSTEXPR T raise_overflow_error(const char* function, const char* message, const T& val, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
+{
+   typedef typename Policy::overflow_error_type policy_type;
+   return detail::raise_overflow_error(
+      function, message ? message : "Overflow evaluating function at %1%",
+      val, policy_type());
+}
+
+template <class T, class Policy>
+inline BOOST_MATH_CONSTEXPR T raise_underflow_error(const char* function, const char* message, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
+{
+   typedef typename Policy::underflow_error_type policy_type;
+   return detail::raise_underflow_error<T>(
+      function, message ? message : "Underflow Error",
+      policy_type());
+}
+
+template <class T, class Policy>
+inline BOOST_MATH_CONSTEXPR T raise_denorm_error(const char* function, const char* message, const T& val, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
+{
+   typedef typename Policy::denorm_error_type policy_type;
+   return detail::raise_denorm_error<T>(
+      function, message ? message : "Denorm Error",
+      val,
+      policy_type());
+}
+
+template <class T, class Policy>
+inline BOOST_MATH_CONSTEXPR T raise_evaluation_error(const char* function, const char* message, const T& val, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
+{
+   typedef typename Policy::evaluation_error_type policy_type;
+   return detail::raise_evaluation_error(
+      function, message ? message : "Internal Evaluation Error, best value so far was %1%",
+      val, policy_type());
+}
+
+template <class T, class TargetType, class Policy>
+inline BOOST_MATH_CONSTEXPR TargetType raise_rounding_error(const char* function, const char* message, const T& val, const TargetType& t, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
+{
+   typedef typename Policy::rounding_error_type policy_type;
+   return detail::raise_rounding_error(
+      function, message ? message : "Value %1% can not be represented in the target integer type.",
+      val, t, policy_type());
+}
+
+template <class T, class R, class Policy>
+inline BOOST_MATH_CONSTEXPR T raise_indeterminate_result_error(const char* function, const char* message, const T& val, const R& result, const Policy&) BOOST_NOEXCEPT_IF(is_noexcept_error_policy<Policy>::value && BOOST_MATH_IS_FLOAT(T))
+{
+   typedef typename Policy::indeterminate_result_error_type policy_type;
+   return detail::raise_indeterminate_result_error(
+      function, message ? message : "Indeterminate result with value %1%",
+      val, result, policy_type());
+}
+
+//
+// checked_narrowing_cast:
+//
+namespace detail
+{
+
+template <class R, class T, class Policy>
+inline bool check_overflow(T val, R* result, const char* function, const Policy& pol) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))
+{
+   BOOST_MATH_STD_USING
+   if(fabs(val) > tools::max_value<R>())
+   {
+      boost::math::policies::detail::raise_overflow_error<R>(function, 0, pol);
+      *result = static_cast<R>(val);
+      return true;
+   }
+   return false;
+}
+template <class R, class T, class Policy>
+inline bool check_overflow(std::complex<T> val, R* result, const char* function, const Policy& pol) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))
+{
+   typedef typename R::value_type r_type;
+   r_type re, im;
+   bool r = check_overflow<r_type>(val.real(), &re, function, pol);
+   r = check_overflow<r_type>(val.imag(), &im, function, pol) || r;
+   *result = R(re, im);
+   return r;
+}
+template <class R, class T, class Policy>
+inline bool check_underflow(T val, R* result, const char* function, const Policy& pol) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))
+{
+   if((val != 0) && (static_cast<R>(val) == 0))
+   {
+      *result = static_cast<R>(boost::math::policies::detail::raise_underflow_error<R>(function, 0, pol));
+      return true;
+   }
+   return false;
+}
+template <class R, class T, class Policy>
+inline bool check_underflow(std::complex<T> val, R* result, const char* function, const Policy& pol) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))
+{
+   typedef typename R::value_type r_type;
+   r_type re, im;
+   bool r = check_underflow<r_type>(val.real(), &re, function, pol);
+   r = check_underflow<r_type>(val.imag(), &im, function, pol) || r;
+   *result = R(re, im);
+   return r;
+}
+template <class R, class T, class Policy>
+inline bool check_denorm(T val, R* result, const char* function, const Policy& pol) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))
+{
+   BOOST_MATH_STD_USING
+   if((fabs(val) < static_cast<T>(tools::min_value<R>())) && (static_cast<R>(val) != 0))
+   {
+      *result = static_cast<R>(boost::math::policies::detail::raise_denorm_error<R>(function, 0, static_cast<R>(val), pol));
+      return true;
+   }
+   return false;
+}
+template <class R, class T, class Policy>
+inline bool check_denorm(std::complex<T> val, R* result, const char* function, const Policy& pol) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error))
+{
+   typedef typename R::value_type r_type;
+   r_type re, im;
+   bool r = check_denorm<r_type>(val.real(), &re, function, pol);
+   r = check_denorm<r_type>(val.imag(), &im, function, pol) || r;
+   *result = R(re, im);
+   return r;
+}
+
+// Default instantiations with ignore_error policy.
+template <class R, class T>
+inline BOOST_MATH_CONSTEXPR bool check_overflow(T /* val */, R* /* result */, const char* /* function */, const overflow_error<ignore_error>&) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) 
+{ return false; }
+template <class R, class T>
+inline BOOST_MATH_CONSTEXPR bool check_overflow(std::complex<T> /* val */, R* /* result */, const char* /* function */, const overflow_error<ignore_error>&) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) 
+{ return false; }
+template <class R, class T>
+inline BOOST_MATH_CONSTEXPR bool check_underflow(T /* val */, R* /* result */, const char* /* function */, const underflow_error<ignore_error>&) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) 
+{ return false; }
+template <class R, class T>
+inline BOOST_MATH_CONSTEXPR bool check_underflow(std::complex<T> /* val */, R* /* result */, const char* /* function */, const underflow_error<ignore_error>&) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) 
+{ return false; }
+template <class R, class T>
+inline BOOST_MATH_CONSTEXPR bool check_denorm(T /* val */, R* /* result*/, const char* /* function */, const denorm_error<ignore_error>&) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) 
+{ return false; }
+template <class R, class T>
+inline BOOST_MATH_CONSTEXPR bool check_denorm(std::complex<T> /* val */, R* /* result*/, const char* /* function */, const denorm_error<ignore_error>&) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) 
+{ return false; }
+
+} // namespace detail
+
+template <class R, class Policy, class T>
+inline R checked_narrowing_cast(T val, const char* function) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy<Policy>::value)
+{
+   typedef typename Policy::overflow_error_type overflow_type;
+   typedef typename Policy::underflow_error_type underflow_type;
+   typedef typename Policy::denorm_error_type denorm_type;
+   //
+   // Most of what follows will evaluate to a no-op:
+   //
+   R result = 0;
+   if(detail::check_overflow<R>(val, &result, function, overflow_type()))
+      return result;
+   if(detail::check_underflow<R>(val, &result, function, underflow_type()))
+      return result;
+   if(detail::check_denorm<R>(val, &result, function, denorm_type()))
+      return result;
+
+   return static_cast<R>(val);
+}
+
+template <class T, class Policy>
+inline void check_series_iterations(const char* function, boost::uintmax_t max_iter, const Policy& pol) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy<Policy>::value)
+{
+   if(max_iter >= policies::get_max_series_iterations<Policy>())
+      raise_evaluation_error<T>(
+         function,
+         "Series evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);
+}
+
+template <class T, class Policy>
+inline void check_root_iterations(const char* function, boost::uintmax_t max_iter, const Policy& pol) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy<Policy>::value)
+{
+   if(max_iter >= policies::get_max_root_iterations<Policy>())
+      raise_evaluation_error<T>(
+         function,
+         "Root finding evaluation exceeded %1% iterations, giving up now.", static_cast<T>(static_cast<double>(max_iter)), pol);
+}
+
+} //namespace policies
+
+namespace detail{
+
+//
+// Simple helper function to assist in returning a pair from a single value,
+// that value usually comes from one of the error handlers above:
+//
+template <class T>
+std::pair<T, T> pair_from_single(const T& val) BOOST_MATH_NOEXCEPT(T)
+{
+   return std::make_pair(val, val);
+}
+
+}
+
+#ifdef BOOST_MSVC
+#  pragma warning(pop)
+#endif
+
+}} // namespaces boost/math
+
+#endif // BOOST_MATH_POLICY_ERROR_HANDLING_HPP
+
diff --git a/ThirdParty/boost/math/quadrature/gauss.hpp b/ThirdParty/boost/math/quadrature/gauss.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b8caee11a9ce1f2937b29ce11a3d6891e601a3e4
--- /dev/null
+++ b/ThirdParty/boost/math/quadrature/gauss.hpp
@@ -0,0 +1,1297 @@
+//  Copyright John Maddock 2015.
+//  Use, modification and distribution are subject to 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_QUADRATURE_GAUSS_HPP
+#define BOOST_MATH_QUADRATURE_GAUSS_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <vector>
+#include <boost/math/special_functions/legendre.hpp>
+#include <boost/math/constants/constants.hpp>
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4127)
+#endif
+
+namespace boost { namespace math{ namespace quadrature{ namespace detail{
+
+template <class T>
+struct gauss_constant_category
+{
+   static const unsigned value =
+      (std::numeric_limits<T>::is_specialized == 0) ? 999 :
+      (std::numeric_limits<T>::radix == 2) ?
+      (
+         (std::numeric_limits<T>::digits <= std::numeric_limits<float>::digits) && boost::is_convertible<float, T>::value ? 0 :
+         (std::numeric_limits<T>::digits <= std::numeric_limits<double>::digits) && boost::is_convertible<double, T>::value ? 1 :
+         (std::numeric_limits<T>::digits <= std::numeric_limits<long double>::digits) && boost::is_convertible<long double, T>::value ? 2 :
+#ifdef BOOST_HAS_FLOAT128
+         (std::numeric_limits<T>::digits <= 113) && boost::is_constructible<__float128, T>::value ? 3 :
+#endif
+         (std::numeric_limits<T>::digits10 <= 110) ? 4 : 999
+      ) : (std::numeric_limits<T>::digits10 <= 110) ? 4 : 999;
+};
+
+#ifndef BOOST_MATH_GAUSS_NO_COMPUTE_ON_DEMAND
+
+template <class Real, unsigned N, unsigned Category>
+class gauss_detail
+{
+   static std::vector<Real> calculate_weights()
+   {
+      std::vector<Real> result(abscissa().size(), 0);
+      for (unsigned i = 0; i < abscissa().size(); ++i)
+      {
+         Real x = abscissa()[i];
+         Real p = boost::math::legendre_p_prime(N, x);
+         result[i] = 2 / ((1 - x * x) * p * p);
+      }
+      return result;
+   }
+public:
+   static const std::vector<Real>& abscissa()
+   {
+      static std::vector<Real> data = boost::math::legendre_p_zeros<Real>(N);
+      return data;
+   }
+   static const std::vector<Real>& weights()
+   {
+      static std::vector<Real> data = calculate_weights();
+      return data;
+   }
+};
+
+#else
+
+template <class Real, unsigned N, unsigned Category>
+class gauss_detail;
+
+#endif
+
+template <class T>
+class gauss_detail<T, 7, 0>
+{
+public:
+   static std::array<T, 4> const & abscissa()
+   {
+      static const std::array<T, 4> data = {
+         0.000000000e+00f,
+         4.058451514e-01f,
+         7.415311856e-01f,
+         9.491079123e-01f,
+      };
+      return data;
+   }
+   static std::array<T, 4> const & weights()
+   {
+      static const std::array<T, 4> data = {
+         4.179591837e-01f,
+         3.818300505e-01f,
+         2.797053915e-01f,
+         1.294849662e-01f,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_detail<T, 7, 1>
+{
+public:
+   static std::array<T, 4> const & abscissa()
+   {
+      static const std::array<T, 4> data = {
+         0.00000000000000000e+00,
+         4.05845151377397167e-01,
+         7.41531185599394440e-01,
+         9.49107912342758525e-01,
+      };
+      return data;
+   }
+   static std::array<T, 4> const & weights()
+   {
+      static const std::array<T, 4> data = {
+         4.17959183673469388e-01,
+         3.81830050505118945e-01,
+         2.79705391489276668e-01,
+         1.29484966168869693e-01,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_detail<T, 7, 2>
+{
+public:
+   static std::array<T, 4> const & abscissa()
+   {
+      static const std::array<T, 4> data = {
+         0.00000000000000000000000000000000000e+00L,
+         4.05845151377397166906606412076961463e-01L,
+         7.41531185599394439863864773280788407e-01L,
+         9.49107912342758524526189684047851262e-01L,
+      };
+      return data;
+   }
+   static std::array<T, 4> const & weights()
+   {
+      static const std::array<T, 4> data = {
+         4.17959183673469387755102040816326531e-01L,
+         3.81830050505118944950369775488975134e-01L,
+         2.79705391489276667901467771423779582e-01L,
+         1.29484966168869693270611432679082018e-01L,
+      };
+      return data;
+   }
+};
+#ifdef BOOST_HAS_FLOAT128
+template <class T>
+class gauss_detail<T, 7, 3>
+{
+public:
+   static std::array<T, 4> const & abscissa()
+   {
+      static const std::array<T, 4> data = {
+         0.00000000000000000000000000000000000e+00Q,
+         4.05845151377397166906606412076961463e-01Q,
+         7.41531185599394439863864773280788407e-01Q,
+         9.49107912342758524526189684047851262e-01Q,
+      };
+      return data;
+   }
+   static std::array<T, 4> const & weights()
+   {
+      static const std::array<T, 4> data = {
+         4.17959183673469387755102040816326531e-01Q,
+         3.81830050505118944950369775488975134e-01Q,
+         2.79705391489276667901467771423779582e-01Q,
+         1.29484966168869693270611432679082018e-01Q,
+      };
+      return data;
+   }
+};
+#endif
+template <class T>
+class gauss_detail<T, 7, 4>
+{
+public:
+   static  std::array<T, 4> const & abscissa()
+   {
+      static  std::array<T, 4> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0584515137739716690660641207696146334738201409937012638704325179466381322612565532831268972774658776528675866604802e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.4153118559939443986386477328078840707414764714139026011995535196742987467218051379282683236686324705969251809311201e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4910791234275852452618968404785126240077093767061778354876910391306333035484014080573077002792572414430073966699522e-01),
+      };
+      return data;
+   }
+   static  std::array<T, 4> const & weights()
+   {
+      static  std::array<T, 4> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.1795918367346938775510204081632653061224489795918367346938775510204081632653061224489795918367346938775510204081633e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.8183005050511894495036977548897513387836508353386273475108345103070554643412970834868465934404480145031467176458536e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.7970539148927666790146777142377958248692506522659876453701403269361881043056267681324094290119761876632337521337205e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2948496616886969327061143267908201832858740225994666397720863872465523497204230871562541816292084508948440200163443e-01),
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_detail<T, 10, 0>
+{
+public:
+   static std::array<T, 5> const & abscissa()
+   {
+      static const std::array<T, 5> data = {
+         1.488743390e-01f,
+         4.333953941e-01f,
+         6.794095683e-01f,
+         8.650633667e-01f,
+         9.739065285e-01f,
+      };
+      return data;
+   }
+   static std::array<T, 5> const & weights()
+   {
+      static const std::array<T, 5> data = {
+         2.955242247e-01f,
+         2.692667193e-01f,
+         2.190863625e-01f,
+         1.494513492e-01f,
+         6.667134431e-02f,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_detail<T, 10, 1>
+{
+public:
+   static std::array<T, 5> const & abscissa()
+   {
+      static const std::array<T, 5> data = {
+         1.48874338981631211e-01,
+         4.33395394129247191e-01,
+         6.79409568299024406e-01,
+         8.65063366688984511e-01,
+         9.73906528517171720e-01,
+      };
+      return data;
+   }
+   static std::array<T, 5> const & weights()
+   {
+      static const std::array<T, 5> data = {
+         2.95524224714752870e-01,
+         2.69266719309996355e-01,
+         2.19086362515982044e-01,
+         1.49451349150580593e-01,
+         6.66713443086881376e-02,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_detail<T, 10, 2>
+{
+public:
+   static std::array<T, 5> const & abscissa()
+   {
+      static const std::array<T, 5> data = {
+         1.48874338981631210884826001129719985e-01L,
+         4.33395394129247190799265943165784162e-01L,
+         6.79409568299024406234327365114873576e-01L,
+         8.65063366688984510732096688423493049e-01L,
+         9.73906528517171720077964012084452053e-01L,
+      };
+      return data;
+   }
+   static std::array<T, 5> const & weights()
+   {
+      static const std::array<T, 5> data = {
+         2.95524224714752870173892994651338329e-01L,
+         2.69266719309996355091226921569469353e-01L,
+         2.19086362515982043995534934228163192e-01L,
+         1.49451349150580593145776339657697332e-01L,
+         6.66713443086881375935688098933317929e-02L,
+      };
+      return data;
+   }
+};
+#ifdef BOOST_HAS_FLOAT128
+template <class T>
+class gauss_detail<T, 10, 3>
+{
+public:
+   static std::array<T, 5> const & abscissa()
+   {
+      static const std::array<T, 5> data = {
+         1.48874338981631210884826001129719985e-01Q,
+         4.33395394129247190799265943165784162e-01Q,
+         6.79409568299024406234327365114873576e-01Q,
+         8.65063366688984510732096688423493049e-01Q,
+         9.73906528517171720077964012084452053e-01Q,
+      };
+      return data;
+   }
+   static std::array<T, 5> const & weights()
+   {
+      static const std::array<T, 5> data = {
+         2.95524224714752870173892994651338329e-01Q,
+         2.69266719309996355091226921569469353e-01Q,
+         2.19086362515982043995534934228163192e-01Q,
+         1.49451349150580593145776339657697332e-01Q,
+         6.66713443086881375935688098933317929e-02Q,
+      };
+      return data;
+   }
+};
+#endif
+template <class T>
+class gauss_detail<T, 10, 4>
+{
+public:
+   static  std::array<T, 5> const & abscissa()
+   {
+      static  std::array<T, 5> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4887433898163121088482600112971998461756485942069169570798925351590361735566852137117762979946369123003116080525534e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.3339539412924719079926594316578416220007183765624649650270151314376698907770350122510275795011772122368293504099894e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.7940956829902440623432736511487357576929471183480946766481718895255857539507492461507857357048037949983390204739932e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6506336668898451073209668842349304852754301496533045252195973184537475513805556135679072894604577069440463108641177e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.7390652851717172007796401208445205342826994669238211923121206669659520323463615962572356495626855625823304251877421e-01),
+      };
+      return data;
+   }
+   static  std::array<T, 5> const & weights()
+   {
+      static  std::array<T, 5> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.9552422471475287017389299465133832942104671702685360135430802975599593821715232927035659579375421672271716440125256e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.6926671930999635509122692156946935285975993846088379580056327624215343231917927676422663670925276075559581145036870e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.1908636251598204399553493422816319245877187052267708988095654363519991065295128124268399317720219278659121687281289e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4945134915058059314577633965769733240255663966942736783547726875323865472663001094594726463473195191400575256104544e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.6671344308688137593568809893331792857864834320158145128694881613412064084087101776785509685058877821090054714520419e-02),
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_detail<T, 15, 0>
+{
+public:
+   static std::array<T, 8> const & abscissa()
+   {
+      static const std::array<T, 8> data = {
+         0.000000000e+00f,
+         2.011940940e-01f,
+         3.941513471e-01f,
+         5.709721726e-01f,
+         7.244177314e-01f,
+         8.482065834e-01f,
+         9.372733924e-01f,
+         9.879925180e-01f,
+      };
+      return data;
+   }
+   static std::array<T, 8> const & weights()
+   {
+      static const std::array<T, 8> data = {
+         2.025782419e-01f,
+         1.984314853e-01f,
+         1.861610000e-01f,
+         1.662692058e-01f,
+         1.395706779e-01f,
+         1.071592205e-01f,
+         7.036604749e-02f,
+         3.075324200e-02f,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_detail<T, 15, 1>
+{
+public:
+   static std::array<T, 8> const & abscissa()
+   {
+      static const std::array<T, 8> data = {
+         0.00000000000000000e+00,
+         2.01194093997434522e-01,
+         3.94151347077563370e-01,
+         5.70972172608538848e-01,
+         7.24417731360170047e-01,
+         8.48206583410427216e-01,
+         9.37273392400705904e-01,
+         9.87992518020485428e-01,
+      };
+      return data;
+   }
+   static std::array<T, 8> const & weights()
+   {
+      static const std::array<T, 8> data = {
+         2.02578241925561273e-01,
+         1.98431485327111576e-01,
+         1.86161000015562211e-01,
+         1.66269205816993934e-01,
+         1.39570677926154314e-01,
+         1.07159220467171935e-01,
+         7.03660474881081247e-02,
+         3.07532419961172684e-02,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_detail<T, 15, 2>
+{
+public:
+   static std::array<T, 8> const & abscissa()
+   {
+      static const std::array<T, 8> data = {
+         0.00000000000000000000000000000000000e+00L,
+         2.01194093997434522300628303394596208e-01L,
+         3.94151347077563369897207370981045468e-01L,
+         5.70972172608538847537226737253910641e-01L,
+         7.24417731360170047416186054613938010e-01L,
+         8.48206583410427216200648320774216851e-01L,
+         9.37273392400705904307758947710209471e-01L,
+         9.87992518020485428489565718586612581e-01L,
+      };
+      return data;
+   }
+   static std::array<T, 8> const & weights()
+   {
+      static const std::array<T, 8> data = {
+         2.02578241925561272880620199967519315e-01L,
+         1.98431485327111576456118326443839325e-01L,
+         1.86161000015562211026800561866422825e-01L,
+         1.66269205816993933553200860481208811e-01L,
+         1.39570677926154314447804794511028323e-01L,
+         1.07159220467171935011869546685869303e-01L,
+         7.03660474881081247092674164506673385e-02L,
+         3.07532419961172683546283935772044177e-02L,
+      };
+      return data;
+   }
+};
+#ifdef BOOST_HAS_FLOAT128
+template <class T>
+class gauss_detail<T, 15, 3>
+{
+public:
+   static std::array<T, 8> const & abscissa()
+   {
+      static const std::array<T, 8> data = {
+         0.00000000000000000000000000000000000e+00Q,
+         2.01194093997434522300628303394596208e-01Q,
+         3.94151347077563369897207370981045468e-01Q,
+         5.70972172608538847537226737253910641e-01Q,
+         7.24417731360170047416186054613938010e-01Q,
+         8.48206583410427216200648320774216851e-01Q,
+         9.37273392400705904307758947710209471e-01Q,
+         9.87992518020485428489565718586612581e-01Q,
+      };
+      return data;
+   }
+   static std::array<T, 8> const & weights()
+   {
+      static const std::array<T, 8> data = {
+         2.02578241925561272880620199967519315e-01Q,
+         1.98431485327111576456118326443839325e-01Q,
+         1.86161000015562211026800561866422825e-01Q,
+         1.66269205816993933553200860481208811e-01Q,
+         1.39570677926154314447804794511028323e-01Q,
+         1.07159220467171935011869546685869303e-01Q,
+         7.03660474881081247092674164506673385e-02Q,
+         3.07532419961172683546283935772044177e-02Q,
+      };
+      return data;
+   }
+};
+#endif
+template <class T>
+class gauss_detail<T, 15, 4>
+{
+public:
+   static  std::array<T, 8> const & abscissa()
+   {
+      static  std::array<T, 8> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0119409399743452230062830339459620781283645446263767961594972460994823900302018760183625806752105908967902257386509e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.9415134707756336989720737098104546836275277615869825503116534395160895778696141797549711416165976202589352169635648e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7097217260853884753722673725391064123838639628274960485326541705419537986975857948341462856982614477912646497026257e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.2441773136017004741618605461393800963089929458410256355142342070412378167792521899610109760313432626923598549381925e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.4820658341042721620064832077421685136625617473699263409572755876067507517414548519760771975082148085090373835713340e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.3727339240070590430775894771020947124399627351530445790136307635020297379704552795054758617426808659746824044603157e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8799251802048542848956571858661258114697281712376148999999751558738843736901942471272205036831914497667516843990079e-01),
+      };
+      return data;
+   }
+   static  std::array<T, 8> const & weights()
+   {
+      static  std::array<T, 8> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0257824192556127288062019996751931483866215800947735679670411605143539875474607409339344071278803213535148267082999e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.9843148532711157645611832644383932481869255995754199348473792792912479753343426813331499916481782320766020854889310e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.8616100001556221102680056186642282450622601227792840281549572731001325550269916061894976888609932360539977709001384e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.6626920581699393355320086048120881113090018009841290732186519056355356321227851771070517429241553621484461540657185e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.3957067792615431444780479451102832252085027531551124320239112863108844454190781168076825736357133363814908889327664e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0715922046717193501186954668586930341554371575810198068702238912187799485231579972568585713760862404439808767837506e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.0366047488108124709267416450667338466708032754330719825907292914387055512874237044840452066693939219355489858595041e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0753241996117268354628393577204417721748144833434074264228285504237189467117168039038770732399404002516991188859473e-02),
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_detail<T, 20, 0>
+{
+public:
+   static std::array<T, 10> const & abscissa()
+   {
+      static const std::array<T, 10> data = {
+         7.652652113e-02f,
+         2.277858511e-01f,
+         3.737060887e-01f,
+         5.108670020e-01f,
+         6.360536807e-01f,
+         7.463319065e-01f,
+         8.391169718e-01f,
+         9.122344283e-01f,
+         9.639719273e-01f,
+         9.931285992e-01f,
+      };
+      return data;
+   }
+   static std::array<T, 10> const & weights()
+   {
+      static const std::array<T, 10> data = {
+         1.527533871e-01f,
+         1.491729865e-01f,
+         1.420961093e-01f,
+         1.316886384e-01f,
+         1.181945320e-01f,
+         1.019301198e-01f,
+         8.327674158e-02f,
+         6.267204833e-02f,
+         4.060142980e-02f,
+         1.761400714e-02f,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_detail<T, 20, 1>
+{
+public:
+   static std::array<T, 10> const & abscissa()
+   {
+      static const std::array<T, 10> data = {
+         7.65265211334973338e-02,
+         2.27785851141645078e-01,
+         3.73706088715419561e-01,
+         5.10867001950827098e-01,
+         6.36053680726515025e-01,
+         7.46331906460150793e-01,
+         8.39116971822218823e-01,
+         9.12234428251325906e-01,
+         9.63971927277913791e-01,
+         9.93128599185094925e-01,
+      };
+      return data;
+   }
+   static std::array<T, 10> const & weights()
+   {
+      static const std::array<T, 10> data = {
+         1.52753387130725851e-01,
+         1.49172986472603747e-01,
+         1.42096109318382051e-01,
+         1.31688638449176627e-01,
+         1.18194531961518417e-01,
+         1.01930119817240435e-01,
+         8.32767415767047487e-02,
+         6.26720483341090636e-02,
+         4.06014298003869413e-02,
+         1.76140071391521183e-02,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_detail<T, 20, 2>
+{
+public:
+   static std::array<T, 10> const & abscissa()
+   {
+      static const std::array<T, 10> data = {
+         7.65265211334973337546404093988382110e-02L,
+         2.27785851141645078080496195368574625e-01L,
+         3.73706088715419560672548177024927237e-01L,
+         5.10867001950827098004364050955250998e-01L,
+         6.36053680726515025452836696226285937e-01L,
+         7.46331906460150792614305070355641590e-01L,
+         8.39116971822218823394529061701520685e-01L,
+         9.12234428251325905867752441203298113e-01L,
+         9.63971927277913791267666131197277222e-01L,
+         9.93128599185094924786122388471320278e-01L,
+      };
+      return data;
+   }
+   static std::array<T, 10> const & weights()
+   {
+      static const std::array<T, 10> data = {
+         1.52753387130725850698084331955097593e-01L,
+         1.49172986472603746787828737001969437e-01L,
+         1.42096109318382051329298325067164933e-01L,
+         1.31688638449176626898494499748163135e-01L,
+         1.18194531961518417312377377711382287e-01L,
+         1.01930119817240435036750135480349876e-01L,
+         8.32767415767047487247581432220462061e-02L,
+         6.26720483341090635695065351870416064e-02L,
+         4.06014298003869413310399522749321099e-02L,
+         1.76140071391521183118619623518528164e-02L,
+      };
+      return data;
+   }
+};
+#ifdef BOOST_HAS_FLOAT128
+template <class T>
+class gauss_detail<T, 20, 3>
+{
+public:
+   static std::array<T, 10> const & abscissa()
+   {
+      static const std::array<T, 10> data = {
+         7.65265211334973337546404093988382110e-02Q,
+         2.27785851141645078080496195368574625e-01Q,
+         3.73706088715419560672548177024927237e-01Q,
+         5.10867001950827098004364050955250998e-01Q,
+         6.36053680726515025452836696226285937e-01Q,
+         7.46331906460150792614305070355641590e-01Q,
+         8.39116971822218823394529061701520685e-01Q,
+         9.12234428251325905867752441203298113e-01Q,
+         9.63971927277913791267666131197277222e-01Q,
+         9.93128599185094924786122388471320278e-01Q,
+      };
+      return data;
+   }
+   static std::array<T, 10> const & weights()
+   {
+      static const std::array<T, 10> data = {
+         1.52753387130725850698084331955097593e-01Q,
+         1.49172986472603746787828737001969437e-01Q,
+         1.42096109318382051329298325067164933e-01Q,
+         1.31688638449176626898494499748163135e-01Q,
+         1.18194531961518417312377377711382287e-01Q,
+         1.01930119817240435036750135480349876e-01Q,
+         8.32767415767047487247581432220462061e-02Q,
+         6.26720483341090635695065351870416064e-02Q,
+         4.06014298003869413310399522749321099e-02Q,
+         1.76140071391521183118619623518528164e-02Q,
+      };
+      return data;
+   }
+};
+#endif
+template <class T>
+class gauss_detail<T, 20, 4>
+{
+public:
+   static  std::array<T, 10> const & abscissa()
+   {
+      static  std::array<T, 10> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6526521133497333754640409398838211004796266813497500804795244384256342048336978241545114181556215606998505646364133e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.2778585114164507808049619536857462474308893768292747231463573920717134186355582779495212519096870803177373131560430e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.7370608871541956067254817702492723739574632170568271182794861351564576437305952789589568363453337894476772208852815e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1086700195082709800436405095525099842549132920242683347234861989473497039076572814403168305086777919832943068843526e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.3605368072651502545283669622628593674338911679936846393944662254654126258543013255870319549576130658211710937772596e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.4633190646015079261430507035564159031073067956917644413954590606853535503815506468110411362064752061238490065167656e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3911697182221882339452906170152068532962936506563737325249272553286109399932480991922934056595764922060422035306914e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.1223442825132590586775244120329811304918479742369177479588221915807089120871907893644472619292138737876039175464603e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6397192727791379126766613119727722191206032780618885606353759389204158078438305698001812525596471563131043491596423e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9312859918509492478612238847132027822264713090165589614818413121798471762775378083944940249657220927472894034724419e-01),
+      };
+      return data;
+   }
+   static  std::array<T, 10> const & weights()
+   {
+      static  std::array<T, 10> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.5275338713072585069808433195509759349194864511237859727470104981759745316273778153557248783650390593544001842813788e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4917298647260374678782873700196943669267990408136831649621121780984442259558678069396132603521048105170913854567338e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4209610931838205132929832506716493303451541339202030333736708298382808749793436761694922428320058260133068573666201e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.3168863844917662689849449974816313491611051114698352699643649370885435642948093314355797518397262924510598005463625e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1819453196151841731237737771138228700504121954896877544688995202017474835051151630572868782581901744606267543092317e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0193011981724043503675013548034987616669165602339255626197161619685232202539434647534931576947985821375859035525483e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3276741576704748724758143222046206100177828583163290744882060785693082894079419471375190843790839349096116111932764e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2672048334109063569506535187041606351601076578436364099584345437974811033665678644563766056832203512603253399592073e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0601429800386941331039952274932109879090639989951536817606854561832296750987328295538920623044384976189825709675075e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.7614007139152118311861962351852816362143105543336732524349326677348419259621847817403105542146097668703716227512570e-02),
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_detail<T, 25, 0>
+{
+public:
+   static std::array<T, 13> const & abscissa()
+   {
+      static const std::array<T, 13> data = {
+         0.000000000e+00f,
+         1.228646926e-01f,
+         2.438668837e-01f,
+         3.611723058e-01f,
+         4.730027314e-01f,
+         5.776629302e-01f,
+         6.735663685e-01f,
+         7.592592630e-01f,
+         8.334426288e-01f,
+         8.949919979e-01f,
+         9.429745712e-01f,
+         9.766639215e-01f,
+         9.955569698e-01f,
+      };
+      return data;
+   }
+   static std::array<T, 13> const & weights()
+   {
+      static const std::array<T, 13> data = {
+         1.231760537e-01f,
+         1.222424430e-01f,
+         1.194557635e-01f,
+         1.148582591e-01f,
+         1.085196245e-01f,
+         1.005359491e-01f,
+         9.102826198e-02f,
+         8.014070034e-02f,
+         6.803833381e-02f,
+         5.490469598e-02f,
+         4.093915670e-02f,
+         2.635498662e-02f,
+         1.139379850e-02f,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_detail<T, 25, 1>
+{
+public:
+   static std::array<T, 13> const & abscissa()
+   {
+      static const std::array<T, 13> data = {
+         0.00000000000000000e+00,
+         1.22864692610710396e-01,
+         2.43866883720988432e-01,
+         3.61172305809387838e-01,
+         4.73002731445714961e-01,
+         5.77662930241222968e-01,
+         6.73566368473468364e-01,
+         7.59259263037357631e-01,
+         8.33442628760834001e-01,
+         8.94991997878275369e-01,
+         9.42974571228974339e-01,
+         9.76663921459517511e-01,
+         9.95556969790498098e-01,
+      };
+      return data;
+   }
+   static std::array<T, 13> const & weights()
+   {
+      static const std::array<T, 13> data = {
+         1.23176053726715451e-01,
+         1.22242442990310042e-01,
+         1.19455763535784772e-01,
+         1.14858259145711648e-01,
+         1.08519624474263653e-01,
+         1.00535949067050644e-01,
+         9.10282619829636498e-02,
+         8.01407003350010180e-02,
+         6.80383338123569172e-02,
+         5.49046959758351919e-02,
+         4.09391567013063127e-02,
+         2.63549866150321373e-02,
+         1.13937985010262879e-02,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_detail<T, 25, 2>
+{
+public:
+   static std::array<T, 13> const & abscissa()
+   {
+      static const std::array<T, 13> data = {
+         0.00000000000000000000000000000000000e+00L,
+         1.22864692610710396387359818808036806e-01L,
+         2.43866883720988432045190362797451586e-01L,
+         3.61172305809387837735821730127640667e-01L,
+         4.73002731445714960522182115009192041e-01L,
+         5.77662930241222967723689841612654067e-01L,
+         6.73566368473468364485120633247622176e-01L,
+         7.59259263037357630577282865204360976e-01L,
+         8.33442628760834001421021108693569569e-01L,
+         8.94991997878275368851042006782804954e-01L,
+         9.42974571228974339414011169658470532e-01L,
+         9.76663921459517511498315386479594068e-01L,
+         9.95556969790498097908784946893901617e-01L,
+      };
+      return data;
+   }
+   static std::array<T, 13> const & weights()
+   {
+      static const std::array<T, 13> data = {
+         1.23176053726715451203902873079050142e-01L,
+         1.22242442990310041688959518945851506e-01L,
+         1.19455763535784772228178126512901047e-01L,
+         1.14858259145711648339325545869555809e-01L,
+         1.08519624474263653116093957050116619e-01L,
+         1.00535949067050644202206890392685827e-01L,
+         9.10282619829636498114972207028916534e-02L,
+         8.01407003350010180132349596691113023e-02L,
+         6.80383338123569172071871856567079686e-02L,
+         5.49046959758351919259368915404733242e-02L,
+         4.09391567013063126556234877116459537e-02L,
+         2.63549866150321372619018152952991449e-02L,
+         1.13937985010262879479029641132347736e-02L,
+      };
+      return data;
+   }
+};
+#ifdef BOOST_HAS_FLOAT128
+template <class T>
+class gauss_detail<T, 25, 3>
+{
+public:
+   static std::array<T, 13> const & abscissa()
+   {
+      static const std::array<T, 13> data = {
+         0.00000000000000000000000000000000000e+00Q,
+         1.22864692610710396387359818808036806e-01Q,
+         2.43866883720988432045190362797451586e-01Q,
+         3.61172305809387837735821730127640667e-01Q,
+         4.73002731445714960522182115009192041e-01Q,
+         5.77662930241222967723689841612654067e-01Q,
+         6.73566368473468364485120633247622176e-01Q,
+         7.59259263037357630577282865204360976e-01Q,
+         8.33442628760834001421021108693569569e-01Q,
+         8.94991997878275368851042006782804954e-01Q,
+         9.42974571228974339414011169658470532e-01Q,
+         9.76663921459517511498315386479594068e-01Q,
+         9.95556969790498097908784946893901617e-01Q,
+      };
+      return data;
+   }
+   static std::array<T, 13> const & weights()
+   {
+      static const std::array<T, 13> data = {
+         1.23176053726715451203902873079050142e-01Q,
+         1.22242442990310041688959518945851506e-01Q,
+         1.19455763535784772228178126512901047e-01Q,
+         1.14858259145711648339325545869555809e-01Q,
+         1.08519624474263653116093957050116619e-01Q,
+         1.00535949067050644202206890392685827e-01Q,
+         9.10282619829636498114972207028916534e-02Q,
+         8.01407003350010180132349596691113023e-02Q,
+         6.80383338123569172071871856567079686e-02Q,
+         5.49046959758351919259368915404733242e-02Q,
+         4.09391567013063126556234877116459537e-02Q,
+         2.63549866150321372619018152952991449e-02Q,
+         1.13937985010262879479029641132347736e-02Q,
+      };
+      return data;
+   }
+};
+#endif
+template <class T>
+class gauss_detail<T, 25, 4>
+{
+public:
+   static  std::array<T, 13> const & abscissa()
+   {
+      static  std::array<T, 13> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2286469261071039638735981880803680553220534604978373842389353789270883496885841582643884994633105537597765980412320e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.4386688372098843204519036279745158640563315632598447642113565325038747278585595067977636776325034060327548499765742e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.6117230580938783773582173012764066742207834704337506979457877784674538239569654860329531506093761400789294612122812e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.7300273144571496052218211500919204133181773846162729090723082769560327584128603010315684778279363544192787010704498e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7766293024122296772368984161265406739573503929151825664548350776102301275263202227671659646579649084013116066120581e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.7356636847346836448512063324762217588341672807274931705965696177828773684928421158196368568030932194044282149314388e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.5925926303735763057728286520436097638752201889833412091838973544501862882026240760763679724185230331463919586229073e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3344262876083400142102110869356956946096411382352078602086471546171813247709012525322973947759168107133491065937347e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.9499199787827536885104200678280495417455484975358390306170168295917151090119945137118600693039178162093726882638296e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4297457122897433941401116965847053190520157060899014192745249713729532254404926130890521815127348327109666786665572e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.7666392145951751149831538647959406774537055531440674467098742731616386753588055389644670948300617866819865983054648e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9555696979049809790878494689390161725756264940480817121080493113293348134372793448728802635294700756868258870429256e-01),
+      };
+      return data;
+   }
+   static  std::array<T, 13> const & weights()
+   {
+      static  std::array<T, 13> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2317605372671545120390287307905014243823362751815166539135219731691200794926142128460112517504958377310054583945994e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2224244299031004168895951894585150583505924756305904090758008223203896721918010243033540891078906637115620156845304e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1945576353578477222817812651290104739017670141372642551958788133518409022018773502442869720975271321374348568426235e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1485825914571164833932554586955580864093619166818014959151499003148279667112542256534429898558156273250513652351744e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0851962447426365311609395705011661934007758798672201615649430734883929279360844269339768350029654172135832773427565e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0053594906705064420220689039268582698846609452814190706986904199941294815904602968195565620373258211755226681206658e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.1028261982963649811497220702891653380992558959334310970483768967017384678410526902484398142953718885872521590850372e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.0140700335001018013234959669111302290225732853675893716201462973612828934801289559457377714225318048243957479325813e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.8038333812356917207187185656707968554709494354636562615071226410003654051711473106651522969481873733098761760660898e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.4904695975835191925936891540473324160109985553111349048508498244593774678436511895711924079433444763756746828817613e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0939156701306312655623487711645953660845783364104346504698414899297432880215512770478971055110424130123527015425511e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.6354986615032137261901815295299144935963281703322468755366165783870934008879499371529821528172928890350362464605104e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1393798501026287947902964113234773603320526292909696448948061116189891729766743355923677112945033505688431618009664e-02),
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_detail<T, 30, 0>
+{
+public:
+   static std::array<T, 15> const & abscissa()
+   {
+      static const std::array<T, 15> data = {
+         5.147184256e-02f,
+         1.538699136e-01f,
+         2.546369262e-01f,
+         3.527047255e-01f,
+         4.470337695e-01f,
+         5.366241481e-01f,
+         6.205261830e-01f,
+         6.978504948e-01f,
+         7.677774321e-01f,
+         8.295657624e-01f,
+         8.825605358e-01f,
+         9.262000474e-01f,
+         9.600218650e-01f,
+         9.836681233e-01f,
+         9.968934841e-01f,
+      };
+      return data;
+   }
+   static std::array<T, 15> const & weights()
+   {
+      static const std::array<T, 15> data = {
+         1.028526529e-01f,
+         1.017623897e-01f,
+         9.959342059e-02f,
+         9.636873717e-02f,
+         9.212252224e-02f,
+         8.689978720e-02f,
+         8.075589523e-02f,
+         7.375597474e-02f,
+         6.597422988e-02f,
+         5.749315622e-02f,
+         4.840267283e-02f,
+         3.879919257e-02f,
+         2.878470788e-02f,
+         1.846646831e-02f,
+         7.968192496e-03f,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_detail<T, 30, 1>
+{
+public:
+   static std::array<T, 15> const & abscissa()
+   {
+      static const std::array<T, 15> data = {
+         5.14718425553176958e-02,
+         1.53869913608583547e-01,
+         2.54636926167889846e-01,
+         3.52704725530878113e-01,
+         4.47033769538089177e-01,
+         5.36624148142019899e-01,
+         6.20526182989242861e-01,
+         6.97850494793315797e-01,
+         7.67777432104826195e-01,
+         8.29565762382768397e-01,
+         8.82560535792052682e-01,
+         9.26200047429274326e-01,
+         9.60021864968307512e-01,
+         9.83668123279747210e-01,
+         9.96893484074649540e-01,
+      };
+      return data;
+   }
+   static std::array<T, 15> const & weights()
+   {
+      static const std::array<T, 15> data = {
+         1.02852652893558840e-01,
+         1.01762389748405505e-01,
+         9.95934205867952671e-02,
+         9.63687371746442596e-02,
+         9.21225222377861287e-02,
+         8.68997872010829798e-02,
+         8.07558952294202154e-02,
+         7.37559747377052063e-02,
+         6.59742298821804951e-02,
+         5.74931562176190665e-02,
+         4.84026728305940529e-02,
+         3.87991925696270496e-02,
+         2.87847078833233693e-02,
+         1.84664683110909591e-02,
+         7.96819249616660562e-03,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_detail<T, 30, 2>
+{
+public:
+   static std::array<T, 15> const & abscissa()
+   {
+      static const std::array<T, 15> data = {
+         5.14718425553176958330252131667225737e-02L,
+         1.53869913608583546963794672743255920e-01L,
+         2.54636926167889846439805129817805108e-01L,
+         3.52704725530878113471037207089373861e-01L,
+         4.47033769538089176780609900322854000e-01L,
+         5.36624148142019899264169793311072794e-01L,
+         6.20526182989242861140477556431189299e-01L,
+         6.97850494793315796932292388026640068e-01L,
+         7.67777432104826194917977340974503132e-01L,
+         8.29565762382768397442898119732501916e-01L,
+         8.82560535792052681543116462530225590e-01L,
+         9.26200047429274325879324277080474004e-01L,
+         9.60021864968307512216871025581797663e-01L,
+         9.83668123279747209970032581605662802e-01L,
+         9.96893484074649540271630050918695283e-01L,
+      };
+      return data;
+   }
+   static std::array<T, 15> const & weights()
+   {
+      static const std::array<T, 15> data = {
+         1.02852652893558840341285636705415044e-01L,
+         1.01762389748405504596428952168554045e-01L,
+         9.95934205867952670627802821035694765e-02L,
+         9.63687371746442596394686263518098651e-02L,
+         9.21225222377861287176327070876187672e-02L,
+         8.68997872010829798023875307151257026e-02L,
+         8.07558952294202153546949384605297309e-02L,
+         7.37559747377052062682438500221907342e-02L,
+         6.59742298821804951281285151159623612e-02L,
+         5.74931562176190664817216894020561288e-02L,
+         4.84026728305940529029381404228075178e-02L,
+         3.87991925696270495968019364463476920e-02L,
+         2.87847078833233693497191796112920436e-02L,
+         1.84664683110909591423021319120472691e-02L,
+         7.96819249616660561546588347467362245e-03L,
+      };
+      return data;
+   }
+};
+#ifdef BOOST_HAS_FLOAT128
+template <class T>
+class gauss_detail<T, 30, 3>
+{
+public:
+   static std::array<T, 15> const & abscissa()
+   {
+      static const std::array<T, 15> data = {
+         5.14718425553176958330252131667225737e-02Q,
+         1.53869913608583546963794672743255920e-01Q,
+         2.54636926167889846439805129817805108e-01Q,
+         3.52704725530878113471037207089373861e-01Q,
+         4.47033769538089176780609900322854000e-01Q,
+         5.36624148142019899264169793311072794e-01Q,
+         6.20526182989242861140477556431189299e-01Q,
+         6.97850494793315796932292388026640068e-01Q,
+         7.67777432104826194917977340974503132e-01Q,
+         8.29565762382768397442898119732501916e-01Q,
+         8.82560535792052681543116462530225590e-01Q,
+         9.26200047429274325879324277080474004e-01Q,
+         9.60021864968307512216871025581797663e-01Q,
+         9.83668123279747209970032581605662802e-01Q,
+         9.96893484074649540271630050918695283e-01Q,
+      };
+      return data;
+   }
+   static std::array<T, 15> const & weights()
+   {
+      static const std::array<T, 15> data = {
+         1.02852652893558840341285636705415044e-01Q,
+         1.01762389748405504596428952168554045e-01Q,
+         9.95934205867952670627802821035694765e-02Q,
+         9.63687371746442596394686263518098651e-02Q,
+         9.21225222377861287176327070876187672e-02Q,
+         8.68997872010829798023875307151257026e-02Q,
+         8.07558952294202153546949384605297309e-02Q,
+         7.37559747377052062682438500221907342e-02Q,
+         6.59742298821804951281285151159623612e-02Q,
+         5.74931562176190664817216894020561288e-02Q,
+         4.84026728305940529029381404228075178e-02Q,
+         3.87991925696270495968019364463476920e-02Q,
+         2.87847078833233693497191796112920436e-02Q,
+         1.84664683110909591423021319120472691e-02Q,
+         7.96819249616660561546588347467362245e-03Q,
+      };
+      return data;
+   }
+};
+#endif
+template <class T>
+class gauss_detail<T, 30, 4>
+{
+public:
+   static  std::array<T, 15> const & abscissa()
+   {
+      static  std::array<T, 15> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1471842555317695833025213166722573749141453666569564255160843987964755210427109055870090707285485841217089963590678e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.5386991360858354696379467274325592041855197124433846171896298291578714851081610139692310651074078557990111754952062e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.5463692616788984643980512981780510788278930330251842616428597508896353156907880290636628138423620257595521678255758e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.5270472553087811347103720708937386065363100802142562659418446890026941623319107866436039675211352945165817827083104e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.4703376953808917678060990032285400016240759386142440975447738172761535172858420700400688872124189834257262048739699e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.3662414814201989926416979331107279416417800693029710545274348291201490861897837863114116009718990258091585830703557e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2052618298924286114047755643118929920736469282952813259505117012433531497488911774115258445532782106478789996137481e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.9785049479331579693229238802664006838235380065395465637972284673997672124315996069538163644008904690545069439941341e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6777743210482619491797734097450313169488361723290845320649438736515857017299504505260960258623968420224697596501719e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.2956576238276839744289811973250191643906869617034167880695298345365650658958163508295244350814016004371545455777732e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.8256053579205268154311646253022559005668914714648423206832605312161626269519165572921583828573210485349058106849548e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.2620004742927432587932427708047400408647453682532906091103713367942299565110232681677288015055886244486106298320068e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6002186496830751221687102558179766293035921740392339948566167242493995770706842922718944370380002378239172677454384e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8366812327974720997003258160566280194031785470971136351718001015114429536479104370207597166035471368057762560137209e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9689348407464954027163005091869528334088203811775079010809429780238769521016374081588201955806171741257405095963817e-01),
+      };
+      return data;
+   }
+   static  std::array<T, 15> const & weights()
+   {
+      static  std::array<T, 15> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0285265289355884034128563670541504386837555706492822258631898667601623865660942939262884632188870916503815852709086e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0176238974840550459642895216855404463270628948712684086426094541964251360531767494547599781978391198881693385887696e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9593420586795267062780282103569476529869263666704277221365146183946660389908809018092299289324184705373523229592037e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6368737174644259639468626351809865096406461430160245912994275732837534742003123724951247818104195363343093583583429e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.2122522237786128717632707087618767196913234418234107527675047001973047070094168298464052916811907158954949394100501e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6899787201082979802387530715125702576753328743545344012222129882153582254261494247955033509639105330215477601953921e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.0755895229420215354694938460529730875892803708439299890258593706051180567026345604212402769217808080749416147400962e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.3755974737705206268243850022190734153770526037049438941269182374599399314635211710401352716638183270192254236882630e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.5974229882180495128128515115962361237442953656660378967031516042143672466094179365819913911598737439478205808271237e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7493156217619066481721689402056128797120670721763134548715799003232147409954376925211999650950125355559974348279846e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.8402672830594052902938140422807517815271809197372736345191936791805425677102152797767439563562263454374645955072007e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.8799192569627049596801936446347692033200976766395352107732789705946970952769793919055026279035105656340228558382274e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.8784707883323369349719179611292043639588894546287496474180122608145988940013933101730206711484171554940392262251283e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.8466468311090959142302131912047269096206533968181403371298365514585599521307973654080519029675417955638095832046164e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.9681924961666056154658834746736224504806965871517212294851633569200384329013332941536616922861735209846506562158817e-03),
+      };
+      return data;
+   }
+};
+
+}
+
+template <class Real, unsigned N, class Policy = boost::math::policies::policy<> >
+class gauss : public detail::gauss_detail<Real, N, detail::gauss_constant_category<Real>::value>
+{
+   typedef detail::gauss_detail<Real, N, detail::gauss_constant_category<Real>::value> base;
+public:
+
+   template <class F>
+   static auto integrate(F f, Real* pL1 = nullptr)->decltype(std::declval<F>()(std::declval<Real>()))
+   {
+     // In many math texts, K represents the field of real or complex numbers.
+     // Too bad we can't put blackboard bold into C++ source!
+      typedef decltype(f(Real(0))) K;
+      using std::abs;
+      unsigned non_zero_start = 1;
+      K result = Real(0);
+      if (N & 1) {
+         result = f(Real(0)) * base::weights()[0];
+      }
+      else {
+         result = 0;
+         non_zero_start = 0;
+      }
+      Real L1 = abs(result);
+      for (unsigned i = non_zero_start; i < base::abscissa().size(); ++i)
+      {
+         K fp = f(base::abscissa()[i]);
+         K fm = f(-base::abscissa()[i]);
+         result += (fp + fm) * base::weights()[i];
+         L1 += (abs(fp) + abs(fm)) *  base::weights()[i];
+      }
+      if (pL1)
+         *pL1 = L1;
+      return result;
+   }
+   template <class F>
+   static auto integrate(F f, Real a, Real b, Real* pL1 = nullptr)->decltype(std::declval<F>()(std::declval<Real>()))
+   {
+      typedef decltype(f(a)) K;
+      static const char* function = "boost::math::quadrature::gauss<%1%>::integrate(f, %1%, %1%)";
+      if (!(boost::math::isnan)(a) && !(boost::math::isnan)(b))
+      {
+         // Infinite limits:
+         Real min_inf = -tools::max_value<Real>();
+         if ((a <= min_inf) && (b >= tools::max_value<Real>()))
+         {
+            auto u = [&](const Real& t)->K
+            {
+               Real t_sq = t*t;
+               Real inv = 1 / (1 - t_sq);
+               K res = f(t*inv)*(1 + t_sq)*inv*inv;
+               return res;
+            };
+            return integrate(u, pL1);
+         }
+
+         // Right limit is infinite:
+         if ((boost::math::isfinite)(a) && (b >= tools::max_value<Real>()))
+         {
+            auto u = [&](const Real& t)->K
+            {
+               Real z = 1 / (t + 1);
+               Real arg = 2 * z + a - 1;
+               K res = f(arg)*z*z;
+               return res;
+            };
+            K Q = Real(2) * integrate(u, pL1);
+            if (pL1)
+            {
+               *pL1 *= 2;
+            }
+            return Q;
+         }
+
+         if ((boost::math::isfinite)(b) && (a <= -tools::max_value<Real>()))
+         {
+            auto v = [&](const Real& t)->K
+            {
+               Real z = 1 / (t + 1);
+               Real arg = 2 * z - 1;
+               K res = f(b - arg) * z * z;
+               return res;
+            };
+            K Q = Real(2) * integrate(v, pL1);
+            if (pL1)
+            {
+               *pL1 *= 2;
+            }
+            return Q;
+         }
+
+         if ((boost::math::isfinite)(a) && (boost::math::isfinite)(b))
+         {
+            if (a == b)
+            {
+               return K(0);
+            }
+            if (b < a)
+            {
+               return -integrate(f, b, a, pL1);
+            }
+            Real avg = (a + b)*constants::half<Real>();
+            Real scale = (b - a)*constants::half<Real>();
+
+            auto u = [&](Real z)->K
+            {
+               return f(avg + scale*z);
+            };
+            K Q = scale*integrate(u, pL1);
+
+            if (pL1)
+            {
+               *pL1 *= scale;
+            }
+            return Q;
+         }
+      }
+      return static_cast<K>(policies::raise_domain_error(function, "The domain of integration is not sensible; please check the bounds.", a, Policy()));
+   }
+};
+
+} // namespace quadrature
+} // namespace math
+} // namespace boost
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // BOOST_MATH_QUADRATURE_GAUSS_HPP
diff --git a/ThirdParty/boost/math/quadrature/gauss_kronrod.hpp b/ThirdParty/boost/math/quadrature/gauss_kronrod.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3deeb8bef4f187f17cdd511e2e950db6ea3acd2a
--- /dev/null
+++ b/ThirdParty/boost/math/quadrature/gauss_kronrod.hpp
@@ -0,0 +1,1954 @@
+//  Copyright John Maddock 2017.
+// Copyright Nick Thompson 2017.
+//  Use, modification and distribution are subject to 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_QUADRATURE_GAUSS_KRONROD_HPP
+#define BOOST_MATH_QUADRATURE_GAUSS_KRONROD_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#pragma warning(push)
+#pragma warning(disable: 4127)
+#endif
+
+#include <vector>
+#include <boost/math/special_functions/legendre.hpp>
+#include <boost/math/special_functions/legendre_stieltjes.hpp>
+#include <boost/math/quadrature/gauss.hpp>
+
+namespace boost { namespace math{ namespace quadrature{ namespace detail{
+
+#ifndef BOOST_MATH_GAUSS_NO_COMPUTE_ON_DEMAND
+
+template <class Real, unsigned N, unsigned tag>
+class gauss_kronrod_detail
+{
+   static legendre_stieltjes<Real> const& get_legendre_stieltjes()
+   {
+      static const legendre_stieltjes<Real> data((N - 1) / 2 + 1);
+      return data;
+   }
+   static std::vector<Real> calculate_abscissa()
+   {
+      static std::vector<Real> result = boost::math::legendre_p_zeros<Real>((N - 1) / 2);
+      const legendre_stieltjes<Real> E = get_legendre_stieltjes();
+      std::vector<Real> ls_zeros = E.zeros();
+      result.insert(result.end(), ls_zeros.begin(), ls_zeros.end());
+      std::sort(result.begin(), result.end());
+      return result;
+   }
+   static std::vector<Real> calculate_weights()
+   {
+      std::vector<Real> result(abscissa().size(), 0);
+      unsigned gauss_order = (N - 1) / 2;
+      unsigned gauss_start = gauss_order & 1 ? 0 : 1;
+      const legendre_stieltjes<Real>& E = get_legendre_stieltjes();
+
+      for (unsigned i = gauss_start; i < abscissa().size(); i += 2)
+      {
+         Real x = abscissa()[i];
+         Real p = boost::math::legendre_p_prime(gauss_order, x);
+         Real gauss_weight = 2 / ((1 - x * x) * p * p);
+         result[i] = gauss_weight + static_cast<Real>(2) / (static_cast<Real>(gauss_order + 1) * legendre_p_prime(gauss_order, x) * E(x));
+      }
+      for (unsigned i = gauss_start ? 0 : 1; i < abscissa().size(); i += 2)
+      {
+         Real x = abscissa()[i];
+         result[i] = static_cast<Real>(2) / (static_cast<Real>(gauss_order + 1) * legendre_p(gauss_order, x) * E.prime(x));
+      }
+      return result;
+   }
+public:
+   static const std::vector<Real>& abscissa()
+   {
+      static std::vector<Real> data = calculate_abscissa();
+      return data;
+   }
+   static const std::vector<Real>& weights()
+   {
+      static std::vector<Real> data = calculate_weights();
+      return data;
+   }
+};
+
+#else
+
+template <class Real, unsigned N, unsigned tag>
+class gauss_kronrod_detail;
+
+#endif
+
+template <class T>
+class gauss_kronrod_detail<T, 15, 0>
+{
+public:
+   static std::array<T, 8> const & abscissa()
+   {
+      static const std::array<T, 8> data = {
+         0.000000000e+00f,
+         2.077849550e-01f,
+         4.058451514e-01f,
+         5.860872355e-01f,
+         7.415311856e-01f,
+         8.648644234e-01f,
+         9.491079123e-01f,
+         9.914553711e-01f,
+      };
+      return data;
+   }
+   static std::array<T, 8> const & weights()
+   {
+      static const std::array<T, 8> data = {
+         2.094821411e-01f,
+         2.044329401e-01f,
+         1.903505781e-01f,
+         1.690047266e-01f,
+         1.406532597e-01f,
+         1.047900103e-01f,
+         6.309209263e-02f,
+         2.293532201e-02f,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_kronrod_detail<T, 15, 1>
+{
+public:
+   static std::array<T, 8> const & abscissa()
+   {
+      static const std::array<T, 8> data = {
+         0.00000000000000000e+00,
+         2.07784955007898468e-01,
+         4.05845151377397167e-01,
+         5.86087235467691130e-01,
+         7.41531185599394440e-01,
+         8.64864423359769073e-01,
+         9.49107912342758525e-01,
+         9.91455371120812639e-01,
+      };
+      return data;
+   }
+   static std::array<T, 8> const & weights()
+   {
+      static const std::array<T, 8> data = {
+         2.09482141084727828e-01,
+         2.04432940075298892e-01,
+         1.90350578064785410e-01,
+         1.69004726639267903e-01,
+         1.40653259715525919e-01,
+         1.04790010322250184e-01,
+         6.30920926299785533e-02,
+         2.29353220105292250e-02,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_kronrod_detail<T, 15, 2>
+{
+public:
+   static std::array<T, 8> const & abscissa()
+   {
+      static const std::array<T, 8> data = {
+         0.00000000000000000000000000000000000e+00L,
+         2.07784955007898467600689403773244913e-01L,
+         4.05845151377397166906606412076961463e-01L,
+         5.86087235467691130294144838258729598e-01L,
+         7.41531185599394439863864773280788407e-01L,
+         8.64864423359769072789712788640926201e-01L,
+         9.49107912342758524526189684047851262e-01L,
+         9.91455371120812639206854697526328517e-01L,
+      };
+      return data;
+   }
+   static std::array<T, 8> const & weights()
+   {
+      static const std::array<T, 8> data = {
+         2.09482141084727828012999174891714264e-01L,
+         2.04432940075298892414161999234649085e-01L,
+         1.90350578064785409913256402421013683e-01L,
+         1.69004726639267902826583426598550284e-01L,
+         1.40653259715525918745189590510237920e-01L,
+         1.04790010322250183839876322541518017e-01L,
+         6.30920926299785532907006631892042867e-02L,
+         2.29353220105292249637320080589695920e-02L,
+      };
+      return data;
+   }
+};
+
+#ifdef BOOST_HAS_FLOAT128
+template <class T>
+class gauss_kronrod_detail<T, 15, 3>
+{
+public:
+   static std::array<T, 8> const & abscissa()
+   {
+      static const std::array<T, 8> data = {
+         0.00000000000000000000000000000000000e+00Q,
+         2.07784955007898467600689403773244913e-01Q,
+         4.05845151377397166906606412076961463e-01Q,
+         5.86087235467691130294144838258729598e-01Q,
+         7.41531185599394439863864773280788407e-01Q,
+         8.64864423359769072789712788640926201e-01Q,
+         9.49107912342758524526189684047851262e-01Q,
+         9.91455371120812639206854697526328517e-01Q,
+      };
+      return data;
+   }
+   static std::array<T, 8> const & weights()
+   {
+      static const std::array<T, 8> data = {
+         2.09482141084727828012999174891714264e-01Q,
+         2.04432940075298892414161999234649085e-01Q,
+         1.90350578064785409913256402421013683e-01Q,
+         1.69004726639267902826583426598550284e-01Q,
+         1.40653259715525918745189590510237920e-01Q,
+         1.04790010322250183839876322541518017e-01Q,
+         6.30920926299785532907006631892042867e-02Q,
+         2.29353220105292249637320080589695920e-02Q,
+      };
+      return data;
+   }
+};
+#endif
+
+template <class T>
+class gauss_kronrod_detail<T, 15, 4>
+{
+public:
+   static  std::array<T, 8> const & abscissa()
+   {
+      static  std::array<T, 8> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0778495500789846760068940377324491347978440714517064971384573461986693844943520226910343227183698530560857645062738e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0584515137739716690660641207696146334738201409937012638704325179466381322612565532831268972774658776528675866604802e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.8608723546769113029414483825872959843678075060436095130499289319880373607444407464511674498935942098956811555121368e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.4153118559939443986386477328078840707414764714139026011995535196742987467218051379282683236686324705969251809311201e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6486442335976907278971278864092620121097230707408814860145771276706770813259572103585847859604590541475281326027862e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4910791234275852452618968404785126240077093767061778354876910391306333035484014080573077002792572414430073966699522e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9145537112081263920685469752632851664204433837033470129108741357244173934653407235924503509626841760744349505339308e-01),
+      };
+      return data;
+   }
+   static  std::array<T, 8> const & weights()
+   {
+      static  std::array<T, 8> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0948214108472782801299917489171426369776208022370431671299800656137515132325648616816908211675949102392971459688215e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0443294007529889241416199923464908471651760418071835742447095312045467698546598879348374292009347554167803659293064e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.9035057806478540991325640242101368282607807545535835588544088036744058072410212679605964605106377593834568683551139e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.6900472663926790282658342659855028410624490030294424149734006755695680921619029112936702403855359908156070095656537e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4065325971552591874518959051023792039988975724799857556174546893312708093090950408097379122415555910759700350860143e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0479001032225018383987632254151801744375665421383061189339065133963746321576289524167571627509311333949422518201492e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.3092092629978553290700663189204286665071157211550707113605545146983997477964874928199170264504441995865872491871943e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.2935322010529224963732008058969591993560811275746992267507430254711815787976075946156368168156289483493617134063245e-02),
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_kronrod_detail<T, 21, 0>
+{
+public:
+   static std::array<T, 11> const & abscissa()
+   {
+      static const std::array<T, 11> data = {
+         0.000000000e+00f,
+         1.488743390e-01f,
+         2.943928627e-01f,
+         4.333953941e-01f,
+         5.627571347e-01f,
+         6.794095683e-01f,
+         7.808177266e-01f,
+         8.650633667e-01f,
+         9.301574914e-01f,
+         9.739065285e-01f,
+         9.956571630e-01f,
+      };
+      return data;
+   }
+   static std::array<T, 11> const & weights()
+   {
+      static const std::array<T, 11> data = {
+         1.494455540e-01f,
+         1.477391049e-01f,
+         1.427759386e-01f,
+         1.347092173e-01f,
+         1.234919763e-01f,
+         1.093871588e-01f,
+         9.312545458e-02f,
+         7.503967481e-02f,
+         5.475589657e-02f,
+         3.255816231e-02f,
+         1.169463887e-02f,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_kronrod_detail<T, 21, 1>
+{
+public:
+   static std::array<T, 11> const & abscissa()
+   {
+      static const std::array<T, 11> data = {
+         0.00000000000000000e+00,
+         1.48874338981631211e-01,
+         2.94392862701460198e-01,
+         4.33395394129247191e-01,
+         5.62757134668604683e-01,
+         6.79409568299024406e-01,
+         7.80817726586416897e-01,
+         8.65063366688984511e-01,
+         9.30157491355708226e-01,
+         9.73906528517171720e-01,
+         9.95657163025808081e-01,
+      };
+      return data;
+   }
+   static std::array<T, 11> const & weights()
+   {
+      static const std::array<T, 11> data = {
+         1.49445554002916906e-01,
+         1.47739104901338491e-01,
+         1.42775938577060081e-01,
+         1.34709217311473326e-01,
+         1.23491976262065851e-01,
+         1.09387158802297642e-01,
+         9.31254545836976055e-02,
+         7.50396748109199528e-02,
+         5.47558965743519960e-02,
+         3.25581623079647275e-02,
+         1.16946388673718743e-02,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_kronrod_detail<T, 21, 2>
+{
+public:
+   static std::array<T, 11> const & abscissa()
+   {
+      static const std::array<T, 11> data = {
+         0.00000000000000000000000000000000000e+00L,
+         1.48874338981631210884826001129719985e-01L,
+         2.94392862701460198131126603103865566e-01L,
+         4.33395394129247190799265943165784162e-01L,
+         5.62757134668604683339000099272694141e-01L,
+         6.79409568299024406234327365114873576e-01L,
+         7.80817726586416897063717578345042377e-01L,
+         8.65063366688984510732096688423493049e-01L,
+         9.30157491355708226001207180059508346e-01L,
+         9.73906528517171720077964012084452053e-01L,
+         9.95657163025808080735527280689002848e-01L,
+      };
+      return data;
+   }
+   static std::array<T, 11> const & weights()
+   {
+      static const std::array<T, 11> data = {
+         1.49445554002916905664936468389821204e-01L,
+         1.47739104901338491374841515972068046e-01L,
+         1.42775938577060080797094273138717061e-01L,
+         1.34709217311473325928054001771706833e-01L,
+         1.23491976262065851077958109831074160e-01L,
+         1.09387158802297641899210590325804960e-01L,
+         9.31254545836976055350654650833663444e-02L,
+         7.50396748109199527670431409161900094e-02L,
+         5.47558965743519960313813002445801764e-02L,
+         3.25581623079647274788189724593897606e-02L,
+         1.16946388673718742780643960621920484e-02L,
+      };
+      return data;
+   }
+};
+
+#ifdef BOOST_HAS_FLOAT128
+template <class T>
+class gauss_kronrod_detail<T, 21, 3>
+{
+public:
+   static std::array<T, 11> const & abscissa()
+   {
+      static const std::array<T, 11> data = {
+         0.00000000000000000000000000000000000e+00Q,
+         1.48874338981631210884826001129719985e-01Q,
+         2.94392862701460198131126603103865566e-01Q,
+         4.33395394129247190799265943165784162e-01Q,
+         5.62757134668604683339000099272694141e-01Q,
+         6.79409568299024406234327365114873576e-01Q,
+         7.80817726586416897063717578345042377e-01Q,
+         8.65063366688984510732096688423493049e-01Q,
+         9.30157491355708226001207180059508346e-01Q,
+         9.73906528517171720077964012084452053e-01Q,
+         9.95657163025808080735527280689002848e-01Q,
+      };
+      return data;
+   }
+   static std::array<T, 11> const & weights()
+   {
+      static const std::array<T, 11> data = {
+         1.49445554002916905664936468389821204e-01Q,
+         1.47739104901338491374841515972068046e-01Q,
+         1.42775938577060080797094273138717061e-01Q,
+         1.34709217311473325928054001771706833e-01Q,
+         1.23491976262065851077958109831074160e-01Q,
+         1.09387158802297641899210590325804960e-01Q,
+         9.31254545836976055350654650833663444e-02Q,
+         7.50396748109199527670431409161900094e-02Q,
+         5.47558965743519960313813002445801764e-02Q,
+         3.25581623079647274788189724593897606e-02Q,
+         1.16946388673718742780643960621920484e-02Q,
+      };
+      return data;
+   }
+};
+#endif
+
+template <class T>
+class gauss_kronrod_detail<T, 21, 4>
+{
+public:
+   static  std::array<T, 11> const & abscissa()
+   {
+      static  std::array<T, 11> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4887433898163121088482600112971998461756485942069169570798925351590361735566852137117762979946369123003116080525534e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.9439286270146019813112660310386556616268662515695791864888229172724611166332737888445523178268237359119185139299872e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.3339539412924719079926594316578416220007183765624649650270151314376698907770350122510275795011772122368293504099894e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.6275713466860468333900009927269414084301388194196695886034621458779266353216327549712087854169992422106448211158815e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.7940956829902440623432736511487357576929471183480946766481718895255857539507492461507857357048037949983390204739932e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.8081772658641689706371757834504237716340752029815717974694859999505607982761420654526977234238996241110129779403362e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6506336668898451073209668842349304852754301496533045252195973184537475513805556135679072894604577069440463108641177e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.3015749135570822600120718005950834622516790998193924230349406866828415983091673055011194572851007884702013619684320e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.7390652851717172007796401208445205342826994669238211923121206669659520323463615962572356495626855625823304251877421e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9565716302580808073552728068900284792126058721947892436337916111757023046774867357152325996912076724298149077812671e-01),
+      };
+      return data;
+   }
+   static  std::array<T, 11> const & weights()
+   {
+      static  std::array<T, 11> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4944555400291690566493646838982120374523631668747280383560851873698964478511841925721030705689540264726493367634340e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4773910490133849137484151597206804552373162548520660451819195439885993016735696405732703959182882254268727823258502e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4277593857706008079709427313871706088597905653190555560741004743970770449909340027811131706283756428281146832304737e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.3470921731147332592805400177170683276099191300855971406636668491320291400121282036676953159488271772384389604997640e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2349197626206585107795810983107415951230034952864832764467994120974054238975454689681538622363738230836484113389878e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0938715880229764189921059032580496027181329983434522007819675829826550372891432168683899432674553842507906611591517e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.3125454583697605535065465083366344390018828880760031970085038760177735672200775237414123061615827474831165614953012e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.5039674810919952767043140916190009395219382000910088173697048048430404342858495178813808730646554086856929327903059e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.4755896574351996031381300244580176373721114058333557524432615804784098927818975325116301569003298086458722055550981e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.2558162307964727478818972459389760617388939845662609571537504232714121820165498692381607605384626494546068817765276e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1694638867371874278064396062192048396217332481931888927598147525622222058064992651806736704969967250888097490233242e-02),
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_kronrod_detail<T, 31, 0>
+{
+public:
+   static std::array<T, 16> const & abscissa()
+   {
+      static const std::array<T, 16> data = {
+         0.000000000e+00f,
+         1.011420669e-01f,
+         2.011940940e-01f,
+         2.991800072e-01f,
+         3.941513471e-01f,
+         4.850818636e-01f,
+         5.709721726e-01f,
+         6.509967413e-01f,
+         7.244177314e-01f,
+         7.904185014e-01f,
+         8.482065834e-01f,
+         8.972645323e-01f,
+         9.372733924e-01f,
+         9.677390757e-01f,
+         9.879925180e-01f,
+         9.980022987e-01f,
+      };
+      return data;
+   }
+   static std::array<T, 16> const & weights()
+   {
+      static const std::array<T, 16> data = {
+         1.013300070e-01f,
+         1.007698455e-01f,
+         9.917359872e-02f,
+         9.664272698e-02f,
+         9.312659817e-02f,
+         8.856444306e-02f,
+         8.308050282e-02f,
+         7.684968076e-02f,
+         6.985412132e-02f,
+         6.200956780e-02f,
+         5.348152469e-02f,
+         4.458975132e-02f,
+         3.534636079e-02f,
+         2.546084733e-02f,
+         1.500794733e-02f,
+         5.377479873e-03f,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_kronrod_detail<T, 31, 1>
+{
+public:
+   static std::array<T, 16> const & abscissa()
+   {
+      static const std::array<T, 16> data = {
+         0.00000000000000000e+00,
+         1.01142066918717499e-01,
+         2.01194093997434522e-01,
+         2.99180007153168812e-01,
+         3.94151347077563370e-01,
+         4.85081863640239681e-01,
+         5.70972172608538848e-01,
+         6.50996741297416971e-01,
+         7.24417731360170047e-01,
+         7.90418501442465933e-01,
+         8.48206583410427216e-01,
+         8.97264532344081901e-01,
+         9.37273392400705904e-01,
+         9.67739075679139134e-01,
+         9.87992518020485428e-01,
+         9.98002298693397060e-01,
+      };
+      return data;
+   }
+   static std::array<T, 16> const & weights()
+   {
+      static const std::array<T, 16> data = {
+         1.01330007014791549e-01,
+         1.00769845523875595e-01,
+         9.91735987217919593e-02,
+         9.66427269836236785e-02,
+         9.31265981708253212e-02,
+         8.85644430562117706e-02,
+         8.30805028231330210e-02,
+         7.68496807577203789e-02,
+         6.98541213187282587e-02,
+         6.20095678006706403e-02,
+         5.34815246909280873e-02,
+         4.45897513247648766e-02,
+         3.53463607913758462e-02,
+         2.54608473267153202e-02,
+         1.50079473293161225e-02,
+         5.37747987292334899e-03,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_kronrod_detail<T, 31, 2>
+{
+public:
+   static std::array<T, 16> const & abscissa()
+   {
+      static const std::array<T, 16> data = {
+         0.00000000000000000000000000000000000e+00L,
+         1.01142066918717499027074231447392339e-01L,
+         2.01194093997434522300628303394596208e-01L,
+         2.99180007153168812166780024266388963e-01L,
+         3.94151347077563369897207370981045468e-01L,
+         4.85081863640239680693655740232350613e-01L,
+         5.70972172608538847537226737253910641e-01L,
+         6.50996741297416970533735895313274693e-01L,
+         7.24417731360170047416186054613938010e-01L,
+         7.90418501442465932967649294817947347e-01L,
+         8.48206583410427216200648320774216851e-01L,
+         8.97264532344081900882509656454495883e-01L,
+         9.37273392400705904307758947710209471e-01L,
+         9.67739075679139134257347978784337225e-01L,
+         9.87992518020485428489565718586612581e-01L,
+         9.98002298693397060285172840152271209e-01L,
+      };
+      return data;
+   }
+   static std::array<T, 16> const & weights()
+   {
+      static const std::array<T, 16> data = {
+         1.01330007014791549017374792767492547e-01L,
+         1.00769845523875595044946662617569722e-01L,
+         9.91735987217919593323931734846031311e-02L,
+         9.66427269836236785051799076275893351e-02L,
+         9.31265981708253212254868727473457186e-02L,
+         8.85644430562117706472754436937743032e-02L,
+         8.30805028231330210382892472861037896e-02L,
+         7.68496807577203788944327774826590067e-02L,
+         6.98541213187282587095200770991474758e-02L,
+         6.20095678006706402851392309608029322e-02L,
+         5.34815246909280872653431472394302968e-02L,
+         4.45897513247648766082272993732796902e-02L,
+         3.53463607913758462220379484783600481e-02L,
+         2.54608473267153201868740010196533594e-02L,
+         1.50079473293161225383747630758072681e-02L,
+         5.37747987292334898779205143012764982e-03L,
+      };
+      return data;
+   }
+};
+
+#ifdef BOOST_HAS_FLOAT128
+template <class T>
+class gauss_kronrod_detail<T, 31, 3>
+{
+public:
+   static std::array<T, 16> const & abscissa()
+   {
+      static const std::array<T, 16> data = {
+         0.00000000000000000000000000000000000e+00Q,
+         1.01142066918717499027074231447392339e-01Q,
+         2.01194093997434522300628303394596208e-01Q,
+         2.99180007153168812166780024266388963e-01Q,
+         3.94151347077563369897207370981045468e-01Q,
+         4.85081863640239680693655740232350613e-01Q,
+         5.70972172608538847537226737253910641e-01Q,
+         6.50996741297416970533735895313274693e-01Q,
+         7.24417731360170047416186054613938010e-01Q,
+         7.90418501442465932967649294817947347e-01Q,
+         8.48206583410427216200648320774216851e-01Q,
+         8.97264532344081900882509656454495883e-01Q,
+         9.37273392400705904307758947710209471e-01Q,
+         9.67739075679139134257347978784337225e-01Q,
+         9.87992518020485428489565718586612581e-01Q,
+         9.98002298693397060285172840152271209e-01Q,
+      };
+      return data;
+   }
+   static std::array<T, 16> const & weights()
+   {
+      static const std::array<T, 16> data = {
+         1.01330007014791549017374792767492547e-01Q,
+         1.00769845523875595044946662617569722e-01Q,
+         9.91735987217919593323931734846031311e-02Q,
+         9.66427269836236785051799076275893351e-02Q,
+         9.31265981708253212254868727473457186e-02Q,
+         8.85644430562117706472754436937743032e-02Q,
+         8.30805028231330210382892472861037896e-02Q,
+         7.68496807577203788944327774826590067e-02Q,
+         6.98541213187282587095200770991474758e-02Q,
+         6.20095678006706402851392309608029322e-02Q,
+         5.34815246909280872653431472394302968e-02Q,
+         4.45897513247648766082272993732796902e-02Q,
+         3.53463607913758462220379484783600481e-02Q,
+         2.54608473267153201868740010196533594e-02Q,
+         1.50079473293161225383747630758072681e-02Q,
+         5.37747987292334898779205143012764982e-03Q,
+      };
+      return data;
+   }
+};
+#endif
+
+template <class T>
+class gauss_kronrod_detail<T, 31, 4>
+{
+public:
+   static  std::array<T, 16> const & abscissa()
+   {
+      static  std::array<T, 16> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0114206691871749902707423144739233878745105740164180495800189504151097862454083050931321451540380998341273193681967e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0119409399743452230062830339459620781283645446263767961594972460994823900302018760183625806752105908967902257386509e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.9918000715316881216678002426638896266160338274382080184125545738918081102513884467602322020157243563662094470221235e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.9415134707756336989720737098104546836275277615869825503116534395160895778696141797549711416165976202589352169635648e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.8508186364023968069365574023235061286633893089407312129367943604080239955167155974371848690848595275551258416303565e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7097217260853884753722673725391064123838639628274960485326541705419537986975857948341462856982614477912646497026257e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.5099674129741697053373589531327469254694822609259966708966160576093305841043840794460394747228060367236079289132544e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.2441773136017004741618605461393800963089929458410256355142342070412378167792521899610109760313432626923598549381925e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.9041850144246593296764929481794734686214051995697617332365280643308302974631807059994738664225445530963711137343440e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.4820658341042721620064832077421685136625617473699263409572755876067507517414548519760771975082148085090373835713340e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.9726453234408190088250965645449588283177871149442786763972687601078537721473771221195399661919716123038835639691946e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.3727339240070590430775894771020947124399627351530445790136307635020297379704552795054758617426808659746824044603157e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6773907567913913425734797878433722528335733730013163797468062226335804249452174804319385048203118506304424717089291e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8799251802048542848956571858661258114697281712376148999999751558738843736901942471272205036831914497667516843990079e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9800229869339706028517284015227120907340644231555723034839427970683348682837134566648979907760125278631896777136104e-01),
+      };
+      return data;
+   }
+   static  std::array<T, 16> const & weights()
+   {
+      static  std::array<T, 16> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0133000701479154901737479276749254677092627259659629246734858372174107615774696665932418050683956749891773195816338e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0076984552387559504494666261756972191634838013536373069278929029488122760822761077475060185965408326901925180106227e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9173598721791959332393173484603131059567260816713281734860095693651563064308745717056680128223790739026832596087552e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6642726983623678505179907627589335136656568630495198973407668882934392359962841826511402504664592185391687490319950e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.3126598170825321225486872747345718561927881321317330560285879189052002874531855060114908990458716740695847509343865e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.8564443056211770647275443693774303212266732690655967817996052574877144544749814260718837576325109922207832119243346e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3080502823133021038289247286103789601554188253368717607281604875233630643885056057630789228337088859687986285569521e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6849680757720378894432777482659006722109101167947000584089097112470821092034084418224731527690291913686588446455555e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.9854121318728258709520077099147475786045435140671549698798093177992675624987998849748628778570667518643649536771245e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2009567800670640285139230960802932190400004210329723569147829395618376206272317333030584268303808639229575334680414e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.3481524690928087265343147239430296771554760947116739813222888752727413616259625439714812475198987513183153639571249e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.4589751324764876608227299373279690223256649667921096570980823211805450700059906366455036418897149593261561551176267e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.5346360791375846222037948478360048122630678992420820868148023340902501837247680978434662724296810081131106317333086e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.5460847326715320186874001019653359397271745046864640508377984982400903447009185267605205778819712848080691366407461e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.5007947329316122538374763075807268094639436437387634979291759700896494746154334398961710227490402528151677469993935e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.3774798729233489877920514301276498183080402431284197876486169536848635554354599213793172596490038991436925569025913e-03),
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_kronrod_detail<T, 41, 0>
+{
+public:
+   static std::array<T, 21> const & abscissa()
+   {
+      static const std::array<T, 21> data = {
+         0.000000000e+00f,
+         7.652652113e-02f,
+         1.526054652e-01f,
+         2.277858511e-01f,
+         3.016278681e-01f,
+         3.737060887e-01f,
+         4.435931752e-01f,
+         5.108670020e-01f,
+         5.751404468e-01f,
+         6.360536807e-01f,
+         6.932376563e-01f,
+         7.463319065e-01f,
+         7.950414288e-01f,
+         8.391169718e-01f,
+         8.782768113e-01f,
+         9.122344283e-01f,
+         9.408226338e-01f,
+         9.639719273e-01f,
+         9.815078775e-01f,
+         9.931285992e-01f,
+         9.988590316e-01f,
+      };
+      return data;
+   }
+   static std::array<T, 21> const & weights()
+   {
+      static const std::array<T, 21> data = {
+         7.660071192e-02f,
+         7.637786767e-02f,
+         7.570449768e-02f,
+         7.458287540e-02f,
+         7.303069033e-02f,
+         7.105442355e-02f,
+         6.864867293e-02f,
+         6.583459713e-02f,
+         6.265323755e-02f,
+         5.911140088e-02f,
+         5.519510535e-02f,
+         5.094457392e-02f,
+         4.643482187e-02f,
+         4.166887333e-02f,
+         3.660016976e-02f,
+         3.128730678e-02f,
+         2.588213360e-02f,
+         2.038837346e-02f,
+         1.462616926e-02f,
+         8.600269856e-03f,
+         3.073583719e-03f,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_kronrod_detail<T, 41, 1>
+{
+public:
+   static std::array<T, 21> const & abscissa()
+   {
+      static const std::array<T, 21> data = {
+         0.00000000000000000e+00,
+         7.65265211334973338e-02,
+         1.52605465240922676e-01,
+         2.27785851141645078e-01,
+         3.01627868114913004e-01,
+         3.73706088715419561e-01,
+         4.43593175238725103e-01,
+         5.10867001950827098e-01,
+         5.75140446819710315e-01,
+         6.36053680726515025e-01,
+         6.93237656334751385e-01,
+         7.46331906460150793e-01,
+         7.95041428837551198e-01,
+         8.39116971822218823e-01,
+         8.78276811252281976e-01,
+         9.12234428251325906e-01,
+         9.40822633831754754e-01,
+         9.63971927277913791e-01,
+         9.81507877450250259e-01,
+         9.93128599185094925e-01,
+         9.98859031588277664e-01,
+      };
+      return data;
+   }
+   static std::array<T, 21> const & weights()
+   {
+      static const std::array<T, 21> data = {
+         7.66007119179996564e-02,
+         7.63778676720807367e-02,
+         7.57044976845566747e-02,
+         7.45828754004991890e-02,
+         7.30306903327866675e-02,
+         7.10544235534440683e-02,
+         6.86486729285216193e-02,
+         6.58345971336184221e-02,
+         6.26532375547811680e-02,
+         5.91114008806395724e-02,
+         5.51951053482859947e-02,
+         5.09445739237286919e-02,
+         4.64348218674976747e-02,
+         4.16688733279736863e-02,
+         3.66001697582007980e-02,
+         3.12873067770327990e-02,
+         2.58821336049511588e-02,
+         2.03883734612665236e-02,
+         1.46261692569712530e-02,
+         8.60026985564294220e-03,
+         3.07358371852053150e-03,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_kronrod_detail<T, 41, 2>
+{
+public:
+   static std::array<T, 21> const & abscissa()
+   {
+      static const std::array<T, 21> data = {
+         0.00000000000000000000000000000000000e+00L,
+         7.65265211334973337546404093988382110e-02L,
+         1.52605465240922675505220241022677528e-01L,
+         2.27785851141645078080496195368574625e-01L,
+         3.01627868114913004320555356858592261e-01L,
+         3.73706088715419560672548177024927237e-01L,
+         4.43593175238725103199992213492640108e-01L,
+         5.10867001950827098004364050955250998e-01L,
+         5.75140446819710315342946036586425133e-01L,
+         6.36053680726515025452836696226285937e-01L,
+         6.93237656334751384805490711845931533e-01L,
+         7.46331906460150792614305070355641590e-01L,
+         7.95041428837551198350638833272787943e-01L,
+         8.39116971822218823394529061701520685e-01L,
+         8.78276811252281976077442995113078467e-01L,
+         9.12234428251325905867752441203298113e-01L,
+         9.40822633831754753519982722212443380e-01L,
+         9.63971927277913791267666131197277222e-01L,
+         9.81507877450250259193342994720216945e-01L,
+         9.93128599185094924786122388471320278e-01L,
+         9.98859031588277663838315576545863010e-01L,
+      };
+      return data;
+   }
+   static std::array<T, 21> const & weights()
+   {
+      static const std::array<T, 21> data = {
+         7.66007119179996564450499015301017408e-02L,
+         7.63778676720807367055028350380610018e-02L,
+         7.57044976845566746595427753766165583e-02L,
+         7.45828754004991889865814183624875286e-02L,
+         7.30306903327866674951894176589131128e-02L,
+         7.10544235534440683057903617232101674e-02L,
+         6.86486729285216193456234118853678017e-02L,
+         6.58345971336184221115635569693979431e-02L,
+         6.26532375547811680258701221742549806e-02L,
+         5.91114008806395723749672206485942171e-02L,
+         5.51951053482859947448323724197773292e-02L,
+         5.09445739237286919327076700503449487e-02L,
+         4.64348218674976747202318809261075168e-02L,
+         4.16688733279736862637883059368947380e-02L,
+         3.66001697582007980305572407072110085e-02L,
+         3.12873067770327989585431193238007379e-02L,
+         2.58821336049511588345050670961531430e-02L,
+         2.03883734612665235980102314327547051e-02L,
+         1.46261692569712529837879603088683562e-02L,
+         8.60026985564294219866178795010234725e-03L,
+         3.07358371852053150121829324603098749e-03L,
+      };
+      return data;
+   }
+};
+
+#ifdef BOOST_HAS_FLOAT128
+template <class T>
+class gauss_kronrod_detail<T, 41, 3>
+{
+public:
+   static std::array<T, 21> const & abscissa()
+   {
+      static const std::array<T, 21> data = {
+         0.00000000000000000000000000000000000e+00Q,
+         7.65265211334973337546404093988382110e-02Q,
+         1.52605465240922675505220241022677528e-01Q,
+         2.27785851141645078080496195368574625e-01Q,
+         3.01627868114913004320555356858592261e-01Q,
+         3.73706088715419560672548177024927237e-01Q,
+         4.43593175238725103199992213492640108e-01Q,
+         5.10867001950827098004364050955250998e-01Q,
+         5.75140446819710315342946036586425133e-01Q,
+         6.36053680726515025452836696226285937e-01Q,
+         6.93237656334751384805490711845931533e-01Q,
+         7.46331906460150792614305070355641590e-01Q,
+         7.95041428837551198350638833272787943e-01Q,
+         8.39116971822218823394529061701520685e-01Q,
+         8.78276811252281976077442995113078467e-01Q,
+         9.12234428251325905867752441203298113e-01Q,
+         9.40822633831754753519982722212443380e-01Q,
+         9.63971927277913791267666131197277222e-01Q,
+         9.81507877450250259193342994720216945e-01Q,
+         9.93128599185094924786122388471320278e-01Q,
+         9.98859031588277663838315576545863010e-01Q,
+      };
+      return data;
+   }
+   static std::array<T, 21> const & weights()
+   {
+      static const std::array<T, 21> data = {
+         7.66007119179996564450499015301017408e-02Q,
+         7.63778676720807367055028350380610018e-02Q,
+         7.57044976845566746595427753766165583e-02Q,
+         7.45828754004991889865814183624875286e-02Q,
+         7.30306903327866674951894176589131128e-02Q,
+         7.10544235534440683057903617232101674e-02Q,
+         6.86486729285216193456234118853678017e-02Q,
+         6.58345971336184221115635569693979431e-02Q,
+         6.26532375547811680258701221742549806e-02Q,
+         5.91114008806395723749672206485942171e-02Q,
+         5.51951053482859947448323724197773292e-02Q,
+         5.09445739237286919327076700503449487e-02Q,
+         4.64348218674976747202318809261075168e-02Q,
+         4.16688733279736862637883059368947380e-02Q,
+         3.66001697582007980305572407072110085e-02Q,
+         3.12873067770327989585431193238007379e-02Q,
+         2.58821336049511588345050670961531430e-02Q,
+         2.03883734612665235980102314327547051e-02Q,
+         1.46261692569712529837879603088683562e-02Q,
+         8.60026985564294219866178795010234725e-03Q,
+         3.07358371852053150121829324603098749e-03Q,
+      };
+      return data;
+   }
+};
+#endif
+
+template <class T>
+class gauss_kronrod_detail<T, 41, 4>
+{
+public:
+   static  std::array<T, 21> const & abscissa()
+   {
+      static  std::array<T, 21> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6526521133497333754640409398838211004796266813497500804795244384256342048336978241545114181556215606998505646364133e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.5260546524092267550522024102267752791167622481841730660174156703809133685751696356987995886397049724808931527012542e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.2778585114164507808049619536857462474308893768292747231463573920717134186355582779495212519096870803177373131560430e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0162786811491300432055535685859226061539650501373092456926374427956957435978384116066498234762220215751079886015902e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.7370608871541956067254817702492723739574632170568271182794861351564576437305952789589568363453337894476772208852815e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.4359317523872510319999221349264010784010101082300309613315028346299543059315258601993479156987847429893626854030516e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1086700195082709800436405095525099842549132920242683347234861989473497039076572814403168305086777919832943068843526e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7514044681971031534294603658642513281381264014771682537415885495717468074720062012357788489049470208285175093670561e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.3605368072651502545283669622628593674338911679936846393944662254654126258543013255870319549576130658211710937772596e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.9323765633475138480549071184593153338642585141021417904687378454301191710739219011546672416325022748282227809465165e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.4633190646015079261430507035564159031073067956917644413954590606853535503815506468110411362064752061238490065167656e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.9504142883755119835063883327278794295938959911578029703855163894322697871710382866701777890251824617748545658564370e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3911697182221882339452906170152068532962936506563737325249272553286109399932480991922934056595764922060422035306914e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.7827681125228197607744299511307846671124526828251164853898086998248145904743220740840261624245683876748360309079747e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.1223442825132590586775244120329811304918479742369177479588221915807089120871907893644472619292138737876039175464603e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4082263383175475351998272221244338027429557377965291059536839973186796006557571220888218676776618448841584569497535e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6397192727791379126766613119727722191206032780618885606353759389204158078438305698001812525596471563131043491596423e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8150787745025025919334299472021694456725093981023759869077533318793098857465723460898060491887511355706497739384103e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9312859918509492478612238847132027822264713090165589614818413121798471762775378083944940249657220927472894034724419e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9885903158827766383831557654586300999957020432629666866666860339324411793311982967839129772854179884971700274369367e-01),
+      };
+      return data;
+   }
+   static  std::array<T, 21> const & weights()
+   {
+      static  std::array<T, 21> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6600711917999656445049901530101740827932500628670118055485349620314721456712029449597396569857880493210849110825276e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6377867672080736705502835038061001800801036764945996714946431116936745542061941050008345047482501253320401746334511e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.5704497684556674659542775376616558263363155900414326194855223272348838596099414841886740468379707283366777797425290e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.4582875400499188986581418362487528616116493572092273080047040726969899567887364227664202642942357104526915332274625e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.3030690332786667495189417658913112760626845234552742380174250771849743831660040966804802312464527721645765620253776e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.1054423553444068305790361723210167412912159322210143921628270586407381879789525901086146473278095159807542174985045e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.8648672928521619345623411885367801715489704958239860400434264173923806029589970941711224257967651039544669425313433e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.5834597133618422111563556969397943147223506343381443709751749639944420314384296347503523810096842402960802728781816e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2653237554781168025870122174254980585819744698897886186553324157100424088919284503451596742588386343548162830898103e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.9111400880639572374967220648594217136419365977042191748388047204015262840407696611508732839851952697839735487615776e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.5195105348285994744832372419777329194753456228153116909812131213177827707884692917845453999535518818940813085110223e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.0944573923728691932707670050344948664836365809262579747517140086119113476866735641054822574173198900379392130050979e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.6434821867497674720231880926107516842127071007077929289994127933243222585938804392953931185146446072587020288747981e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.1668873327973686263788305936894738043960843153010324860966353235271889596379726462208702081068715463576895020003842e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.6600169758200798030557240707211008487453496747498001651070009441973280061489266074044986901436324295513243878212345e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.1287306777032798958543119323800737887769280362813337359554598005322423266047996771926031069705049476071896145456496e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.5882133604951158834505067096153142999479118048674944526997797755374306421629440393392427198869345793286369198147609e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0388373461266523598010231432754705122838627940185929365371868214433006532030353671253640300679157504987977281782909e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4626169256971252983787960308868356163881050162249770342103474631076960029748751959380482484308382288261238476948520e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6002698556429421986617879501023472521289227667077976622450602031426535362696437838448828009554532025301579670206091e-03),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0735837185205315012182932460309874880335046882543449198461628212114333665590378156706265241414469306987988292234740e-03),
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_kronrod_detail<T, 51, 0>
+{
+public:
+   static std::array<T, 26> const & abscissa()
+   {
+      static const std::array<T, 26> data = {
+         0.000000000e+00f,
+         6.154448301e-02f,
+         1.228646926e-01f,
+         1.837189394e-01f,
+         2.438668837e-01f,
+         3.030895389e-01f,
+         3.611723058e-01f,
+         4.178853822e-01f,
+         4.730027314e-01f,
+         5.263252843e-01f,
+         5.776629302e-01f,
+         6.268100990e-01f,
+         6.735663685e-01f,
+         7.177664068e-01f,
+         7.592592630e-01f,
+         7.978737980e-01f,
+         8.334426288e-01f,
+         8.658470653e-01f,
+         8.949919979e-01f,
+         9.207471153e-01f,
+         9.429745712e-01f,
+         9.616149864e-01f,
+         9.766639215e-01f,
+         9.880357945e-01f,
+         9.955569698e-01f,
+         9.992621050e-01f,
+      };
+      return data;
+   }
+   static std::array<T, 26> const & weights()
+   {
+      static const std::array<T, 26> data = {
+         6.158081807e-02f,
+         6.147118987e-02f,
+         6.112850972e-02f,
+         6.053945538e-02f,
+         5.972034032e-02f,
+         5.868968002e-02f,
+         5.743711636e-02f,
+         5.595081122e-02f,
+         5.425112989e-02f,
+         5.236288581e-02f,
+         5.027767908e-02f,
+         4.798253714e-02f,
+         4.550291305e-02f,
+         4.287284502e-02f,
+         4.008382550e-02f,
+         3.711627148e-02f,
+         3.400213027e-02f,
+         3.079230017e-02f,
+         2.747531759e-02f,
+         2.400994561e-02f,
+         2.043537115e-02f,
+         1.684781771e-02f,
+         1.323622920e-02f,
+         9.473973386e-03f,
+         5.561932135e-03f,
+         1.987383892e-03f,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_kronrod_detail<T, 51, 1>
+{
+public:
+   static std::array<T, 26> const & abscissa()
+   {
+      static const std::array<T, 26> data = {
+         0.00000000000000000e+00,
+         6.15444830056850789e-02,
+         1.22864692610710396e-01,
+         1.83718939421048892e-01,
+         2.43866883720988432e-01,
+         3.03089538931107830e-01,
+         3.61172305809387838e-01,
+         4.17885382193037749e-01,
+         4.73002731445714961e-01,
+         5.26325284334719183e-01,
+         5.77662930241222968e-01,
+         6.26810099010317413e-01,
+         6.73566368473468364e-01,
+         7.17766406813084388e-01,
+         7.59259263037357631e-01,
+         7.97873797998500059e-01,
+         8.33442628760834001e-01,
+         8.65847065293275595e-01,
+         8.94991997878275369e-01,
+         9.20747115281701562e-01,
+         9.42974571228974339e-01,
+         9.61614986425842512e-01,
+         9.76663921459517511e-01,
+         9.88035794534077248e-01,
+         9.95556969790498098e-01,
+         9.99262104992609834e-01,
+      };
+      return data;
+   }
+   static std::array<T, 26> const & weights()
+   {
+      static const std::array<T, 26> data = {
+         6.15808180678329351e-02,
+         6.14711898714253167e-02,
+         6.11285097170530483e-02,
+         6.05394553760458629e-02,
+         5.97203403241740600e-02,
+         5.86896800223942080e-02,
+         5.74371163615678329e-02,
+         5.59508112204123173e-02,
+         5.42511298885454901e-02,
+         5.23628858064074759e-02,
+         5.02776790807156720e-02,
+         4.79825371388367139e-02,
+         4.55029130499217889e-02,
+         4.28728450201700495e-02,
+         4.00838255040323821e-02,
+         3.71162714834155436e-02,
+         3.40021302743293378e-02,
+         3.07923001673874889e-02,
+         2.74753175878517378e-02,
+         2.40099456069532162e-02,
+         2.04353711458828355e-02,
+         1.68478177091282982e-02,
+         1.32362291955716748e-02,
+         9.47397338617415161e-03,
+         5.56193213535671376e-03,
+         1.98738389233031593e-03,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_kronrod_detail<T, 51, 2>
+{
+public:
+   static std::array<T, 26> const & abscissa()
+   {
+      static const std::array<T, 26> data = {
+         0.00000000000000000000000000000000000e+00L,
+         6.15444830056850788865463923667966313e-02L,
+         1.22864692610710396387359818808036806e-01L,
+         1.83718939421048892015969888759528416e-01L,
+         2.43866883720988432045190362797451586e-01L,
+         3.03089538931107830167478909980339329e-01L,
+         3.61172305809387837735821730127640667e-01L,
+         4.17885382193037748851814394594572487e-01L,
+         4.73002731445714960522182115009192041e-01L,
+         5.26325284334719182599623778158010178e-01L,
+         5.77662930241222967723689841612654067e-01L,
+         6.26810099010317412788122681624517881e-01L,
+         6.73566368473468364485120633247622176e-01L,
+         7.17766406813084388186654079773297781e-01L,
+         7.59259263037357630577282865204360976e-01L,
+         7.97873797998500059410410904994306569e-01L,
+         8.33442628760834001421021108693569569e-01L,
+         8.65847065293275595448996969588340088e-01L,
+         8.94991997878275368851042006782804954e-01L,
+         9.20747115281701561746346084546330632e-01L,
+         9.42974571228974339414011169658470532e-01L,
+         9.61614986425842512418130033660167242e-01L,
+         9.76663921459517511498315386479594068e-01L,
+         9.88035794534077247637331014577406227e-01L,
+         9.95556969790498097908784946893901617e-01L,
+         9.99262104992609834193457486540340594e-01L,
+      };
+      return data;
+   }
+   static std::array<T, 26> const & weights()
+   {
+      static const std::array<T, 26> data = {
+         6.15808180678329350787598242400645532e-02L,
+         6.14711898714253166615441319652641776e-02L,
+         6.11285097170530483058590304162927119e-02L,
+         6.05394553760458629453602675175654272e-02L,
+         5.97203403241740599790992919325618538e-02L,
+         5.86896800223942079619741758567877641e-02L,
+         5.74371163615678328535826939395064720e-02L,
+         5.59508112204123173082406863827473468e-02L,
+         5.42511298885454901445433704598756068e-02L,
+         5.23628858064074758643667121378727149e-02L,
+         5.02776790807156719633252594334400844e-02L,
+         4.79825371388367139063922557569147550e-02L,
+         4.55029130499217889098705847526603930e-02L,
+         4.28728450201700494768957924394951611e-02L,
+         4.00838255040323820748392844670756464e-02L,
+         3.71162714834155435603306253676198760e-02L,
+         3.40021302743293378367487952295512032e-02L,
+         3.07923001673874888911090202152285856e-02L,
+         2.74753175878517378029484555178110786e-02L,
+         2.40099456069532162200924891648810814e-02L,
+         2.04353711458828354565682922359389737e-02L,
+         1.68478177091282982315166675363363158e-02L,
+         1.32362291955716748136564058469762381e-02L,
+         9.47397338617415160720771052365532387e-03L,
+         5.56193213535671375804023690106552207e-03L,
+         1.98738389233031592650785188284340989e-03L,
+      };
+      return data;
+   }
+};
+
+#ifdef BOOST_HAS_FLOAT128
+template <class T>
+class gauss_kronrod_detail<T, 51, 3>
+{
+public:
+   static std::array<T, 26> const & abscissa()
+   {
+      static const std::array<T, 26> data = {
+         0.00000000000000000000000000000000000e+00Q,
+         6.15444830056850788865463923667966313e-02Q,
+         1.22864692610710396387359818808036806e-01Q,
+         1.83718939421048892015969888759528416e-01Q,
+         2.43866883720988432045190362797451586e-01Q,
+         3.03089538931107830167478909980339329e-01Q,
+         3.61172305809387837735821730127640667e-01Q,
+         4.17885382193037748851814394594572487e-01Q,
+         4.73002731445714960522182115009192041e-01Q,
+         5.26325284334719182599623778158010178e-01Q,
+         5.77662930241222967723689841612654067e-01Q,
+         6.26810099010317412788122681624517881e-01Q,
+         6.73566368473468364485120633247622176e-01Q,
+         7.17766406813084388186654079773297781e-01Q,
+         7.59259263037357630577282865204360976e-01Q,
+         7.97873797998500059410410904994306569e-01Q,
+         8.33442628760834001421021108693569569e-01Q,
+         8.65847065293275595448996969588340088e-01Q,
+         8.94991997878275368851042006782804954e-01Q,
+         9.20747115281701561746346084546330632e-01Q,
+         9.42974571228974339414011169658470532e-01Q,
+         9.61614986425842512418130033660167242e-01Q,
+         9.76663921459517511498315386479594068e-01Q,
+         9.88035794534077247637331014577406227e-01Q,
+         9.95556969790498097908784946893901617e-01Q,
+         9.99262104992609834193457486540340594e-01Q,
+      };
+      return data;
+   }
+   static std::array<T, 26> const & weights()
+   {
+      static const std::array<T, 26> data = {
+         6.15808180678329350787598242400645532e-02Q,
+         6.14711898714253166615441319652641776e-02Q,
+         6.11285097170530483058590304162927119e-02Q,
+         6.05394553760458629453602675175654272e-02Q,
+         5.97203403241740599790992919325618538e-02Q,
+         5.86896800223942079619741758567877641e-02Q,
+         5.74371163615678328535826939395064720e-02Q,
+         5.59508112204123173082406863827473468e-02Q,
+         5.42511298885454901445433704598756068e-02Q,
+         5.23628858064074758643667121378727149e-02Q,
+         5.02776790807156719633252594334400844e-02Q,
+         4.79825371388367139063922557569147550e-02Q,
+         4.55029130499217889098705847526603930e-02Q,
+         4.28728450201700494768957924394951611e-02Q,
+         4.00838255040323820748392844670756464e-02Q,
+         3.71162714834155435603306253676198760e-02Q,
+         3.40021302743293378367487952295512032e-02Q,
+         3.07923001673874888911090202152285856e-02Q,
+         2.74753175878517378029484555178110786e-02Q,
+         2.40099456069532162200924891648810814e-02Q,
+         2.04353711458828354565682922359389737e-02Q,
+         1.68478177091282982315166675363363158e-02Q,
+         1.32362291955716748136564058469762381e-02Q,
+         9.47397338617415160720771052365532387e-03Q,
+         5.56193213535671375804023690106552207e-03Q,
+         1.98738389233031592650785188284340989e-03Q,
+      };
+      return data;
+   }
+};
+#endif
+
+template <class T>
+class gauss_kronrod_detail<T, 51, 4>
+{
+public:
+   static  std::array<T, 26> const & abscissa()
+   {
+      static  std::array<T, 26> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.1544483005685078886546392366796631281724348039823545274305431751687279361558658545141048781022691067898008423227288e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2286469261071039638735981880803680553220534604978373842389353789270883496885841582643884994633105537597765980412320e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.8371893942104889201596988875952841578528447834990555215034512653236752851109815617651867160645591242103823539931527e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.4386688372098843204519036279745158640563315632598447642113565325038747278585595067977636776325034060327548499765742e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0308953893110783016747890998033932920041937876655194685731578452573120372337209717349617882111662416355753711853559e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.6117230580938783773582173012764066742207834704337506979457877784674538239569654860329531506093761400789294612122812e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.1788538219303774885181439459457248709336998140069528034955785068796932076966599548717224205109797297615032607570119e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.7300273144571496052218211500919204133181773846162729090723082769560327584128603010315684778279363544192787010704498e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.2632528433471918259962377815801017803683252320191114313002425180471455022502695302371008520604638341970901082293650e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7766293024122296772368984161265406739573503929151825664548350776102301275263202227671659646579649084013116066120581e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2681009901031741278812268162451788101954628995068510806525222008437260184181183053045236423845198752346149030569920e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.7356636847346836448512063324762217588341672807274931705965696177828773684928421158196368568030932194044282149314388e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.1776640681308438818665407977329778059771167555515582423493486823991612820974965089522905953765860328116692570706602e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.5925926303735763057728286520436097638752201889833412091838973544501862882026240760763679724185230331463919586229073e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.9787379799850005941041090499430656940863230009338267661706934499488650817643824077118950314443984031474353711531825e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3344262876083400142102110869356956946096411382352078602086471546171813247709012525322973947759168107133491065937347e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6584706529327559544899696958834008820284409402823690293965213246691432948180280120756708738064779055576005302835351e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.9499199787827536885104200678280495417455484975358390306170168295917151090119945137118600693039178162093726882638296e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.2074711528170156174634608454633063157457035996277199700642836501131385042631212407808952281702820179915510491592339e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4297457122897433941401116965847053190520157060899014192745249713729532254404926130890521815127348327109666786665572e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6161498642584251241813003366016724169212642963709676666624520141292893281185666917636407790823210892689040877316178e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.7666392145951751149831538647959406774537055531440674467098742731616386753588055389644670948300617866819865983054648e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8803579453407724763733101457740622707248415209160748131449972199405186821347293686245404742032360498210710718706868e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9555696979049809790878494689390161725756264940480817121080493113293348134372793448728802635294700756868258870429256e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9926210499260983419345748654034059370452496042279618586228697762904524428167719073818746102238075978747461480736921e-01),
+      };
+      return data;
+   }
+   static  std::array<T, 26> const & weights()
+   {
+      static  std::array<T, 26> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.1580818067832935078759824240064553190436936903140808056908996403358367244202623293256774502185186717703954810463664e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.1471189871425316661544131965264177586537962876885022711111683500151700796198726558483367566537422877227096643444043e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.1128509717053048305859030416292711922678552321960938357322028070390133769952032831204895569347757809858568165047769e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.0539455376045862945360267517565427162312365710457079923487043144554747810689514408013582515489930908693681447570811e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.9720340324174059979099291932561853835363045476189975483372207816149988460708299020779612375010639778624011960832019e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.8689680022394207961974175856787764139795646254828315293243700305012569486054157617049685031506591863121580010947248e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7437116361567832853582693939506471994832856823896682976509412313367495727224381199978598247737089593472710899482737e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.5950811220412317308240686382747346820271035112771802428932791066115158268338607019365831655460314732208940609352540e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.4251129888545490144543370459875606826076838441263383072163293312936923476650934130242315028422047795830492882862973e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.2362885806407475864366712137872714887351550723707596350905793656046659248541276597504566497990926306481919129870507e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.0277679080715671963325259433440084440587630604775975142050968279743014641141402310302584542633557037153607386127936e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.7982537138836713906392255756914754983592207423271169651235865196757913880334117810235517477328110033499422471098658e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.5502913049921788909870584752660393043707768935695327316724254392794299567957035458208970599641697203261236226745020e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.2872845020170049476895792439495161101999504199883328877919242515738957655253932048951366960802592343905647433925806e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0083825504032382074839284467075646401410549266591308713115878386835777315058451955614116158949614066927183232852042e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.7116271483415543560330625367619875995997802688047764805628702762773009669395760582294525748583875707140577080663373e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.4002130274329337836748795229551203225670528250050443083264193121524339063344855010257660547708022429300203676502386e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0792300167387488891109020215228585600877162393292487644544830559965388047996492709248618249084851477787538356572832e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.7475317587851737802948455517811078614796013288710603199613621069727810352835469926107822047433566792405123805901196e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.4009945606953216220092489164881081392931528209659330290734972342536012282191913069778658241972047765300060007037359e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0435371145882835456568292235938973678758006097668937220074531550163622566841885855957623103354443247806459277197725e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.6847817709128298231516667536336315840402654624706139411175769276842182270078960078544597372646532637619276509222462e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.3236229195571674813656405846976238077578084997863654732213860488560614587634395544002156258192582265590155862296710e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4739733861741516072077105236553238716453268483726334971394029603529306140359023187904705754719643032594360138998941e-03),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.5619321353567137580402369010655220701769295496290984052961210793810038857581724171021610100708799763006942755331129e-03),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.9873838923303159265078518828434098894299804282505973837653346298985629336820118753523093675303476883723992297810124e-03),
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_kronrod_detail<T, 61, 0>
+{
+public:
+   static std::array<T, 31> const & abscissa()
+   {
+      static const std::array<T, 31> data = {
+         0.000000000e+00f,
+         5.147184256e-02f,
+         1.028069380e-01f,
+         1.538699136e-01f,
+         2.045251167e-01f,
+         2.546369262e-01f,
+         3.040732023e-01f,
+         3.527047255e-01f,
+         4.004012548e-01f,
+         4.470337695e-01f,
+         4.924804679e-01f,
+         5.366241481e-01f,
+         5.793452358e-01f,
+         6.205261830e-01f,
+         6.600610641e-01f,
+         6.978504948e-01f,
+         7.337900625e-01f,
+         7.677774321e-01f,
+         7.997278358e-01f,
+         8.295657624e-01f,
+         8.572052335e-01f,
+         8.825605358e-01f,
+         9.055733077e-01f,
+         9.262000474e-01f,
+         9.443744447e-01f,
+         9.600218650e-01f,
+         9.731163225e-01f,
+         9.836681233e-01f,
+         9.916309969e-01f,
+         9.968934841e-01f,
+         9.994844101e-01f,
+      };
+      return data;
+   }
+   static std::array<T, 31> const & weights()
+   {
+      static const std::array<T, 31> data = {
+         5.149472943e-02f,
+         5.142612854e-02f,
+         5.122154785e-02f,
+         5.088179590e-02f,
+         5.040592140e-02f,
+         4.979568343e-02f,
+         4.905543456e-02f,
+         4.818586176e-02f,
+         4.718554657e-02f,
+         4.605923827e-02f,
+         4.481480013e-02f,
+         4.345253970e-02f,
+         4.196981022e-02f,
+         4.037453895e-02f,
+         3.867894562e-02f,
+         3.688236465e-02f,
+         3.497933803e-02f,
+         3.298144706e-02f,
+         3.090725756e-02f,
+         2.875404877e-02f,
+         2.650995488e-02f,
+         2.419116208e-02f,
+         2.182803582e-02f,
+         1.941414119e-02f,
+         1.692088919e-02f,
+         1.436972951e-02f,
+         1.182301525e-02f,
+         9.273279660e-03f,
+         6.630703916e-03f,
+         3.890461127e-03f,
+         1.389013699e-03f,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_kronrod_detail<T, 61, 1>
+{
+public:
+   static std::array<T, 31> const & abscissa()
+   {
+      static const std::array<T, 31> data = {
+         0.00000000000000000e+00,
+         5.14718425553176958e-02,
+         1.02806937966737030e-01,
+         1.53869913608583547e-01,
+         2.04525116682309891e-01,
+         2.54636926167889846e-01,
+         3.04073202273625077e-01,
+         3.52704725530878113e-01,
+         4.00401254830394393e-01,
+         4.47033769538089177e-01,
+         4.92480467861778575e-01,
+         5.36624148142019899e-01,
+         5.79345235826361692e-01,
+         6.20526182989242861e-01,
+         6.60061064126626961e-01,
+         6.97850494793315797e-01,
+         7.33790062453226805e-01,
+         7.67777432104826195e-01,
+         7.99727835821839083e-01,
+         8.29565762382768397e-01,
+         8.57205233546061099e-01,
+         8.82560535792052682e-01,
+         9.05573307699907799e-01,
+         9.26200047429274326e-01,
+         9.44374444748559979e-01,
+         9.60021864968307512e-01,
+         9.73116322501126268e-01,
+         9.83668123279747210e-01,
+         9.91630996870404595e-01,
+         9.96893484074649540e-01,
+         9.99484410050490638e-01,
+      };
+      return data;
+   }
+   static std::array<T, 31> const & weights()
+   {
+      static const std::array<T, 31> data = {
+         5.14947294294515676e-02,
+         5.14261285374590259e-02,
+         5.12215478492587722e-02,
+         5.08817958987496065e-02,
+         5.04059214027823468e-02,
+         4.97956834270742064e-02,
+         4.90554345550297789e-02,
+         4.81858617570871291e-02,
+         4.71855465692991539e-02,
+         4.60592382710069881e-02,
+         4.48148001331626632e-02,
+         4.34525397013560693e-02,
+         4.19698102151642461e-02,
+         4.03745389515359591e-02,
+         3.86789456247275930e-02,
+         3.68823646518212292e-02,
+         3.49793380280600241e-02,
+         3.29814470574837260e-02,
+         3.09072575623877625e-02,
+         2.87540487650412928e-02,
+         2.65099548823331016e-02,
+         2.41911620780806014e-02,
+         2.18280358216091923e-02,
+         1.94141411939423812e-02,
+         1.69208891890532726e-02,
+         1.43697295070458048e-02,
+         1.18230152534963417e-02,
+         9.27327965951776343e-03,
+         6.63070391593129217e-03,
+         3.89046112709988405e-03,
+         1.38901369867700762e-03,
+      };
+      return data;
+   }
+};
+
+template <class T>
+class gauss_kronrod_detail<T, 61, 2>
+{
+public:
+   static std::array<T, 31> const & abscissa()
+   {
+      static const std::array<T, 31> data = {
+         0.00000000000000000000000000000000000e+00L,
+         5.14718425553176958330252131667225737e-02L,
+         1.02806937966737030147096751318000592e-01L,
+         1.53869913608583546963794672743255920e-01L,
+         2.04525116682309891438957671002024710e-01L,
+         2.54636926167889846439805129817805108e-01L,
+         3.04073202273625077372677107199256554e-01L,
+         3.52704725530878113471037207089373861e-01L,
+         4.00401254830394392535476211542660634e-01L,
+         4.47033769538089176780609900322854000e-01L,
+         4.92480467861778574993693061207708796e-01L,
+         5.36624148142019899264169793311072794e-01L,
+         5.79345235826361691756024932172540496e-01L,
+         6.20526182989242861140477556431189299e-01L,
+         6.60061064126626961370053668149270753e-01L,
+         6.97850494793315796932292388026640068e-01L,
+         7.33790062453226804726171131369527646e-01L,
+         7.67777432104826194917977340974503132e-01L,
+         7.99727835821839083013668942322683241e-01L,
+         8.29565762382768397442898119732501916e-01L,
+         8.57205233546061098958658510658943857e-01L,
+         8.82560535792052681543116462530225590e-01L,
+         9.05573307699907798546522558925958320e-01L,
+         9.26200047429274325879324277080474004e-01L,
+         9.44374444748559979415831324037439122e-01L,
+         9.60021864968307512216871025581797663e-01L,
+         9.73116322501126268374693868423706885e-01L,
+         9.83668123279747209970032581605662802e-01L,
+         9.91630996870404594858628366109485725e-01L,
+         9.96893484074649540271630050918695283e-01L,
+         9.99484410050490637571325895705810819e-01L,
+      };
+      return data;
+   }
+   static std::array<T, 31> const & weights()
+   {
+      static const std::array<T, 31> data = {
+         5.14947294294515675583404336470993075e-02L,
+         5.14261285374590259338628792157812598e-02L,
+         5.12215478492587721706562826049442083e-02L,
+         5.08817958987496064922974730498046919e-02L,
+         5.04059214027823468408930856535850289e-02L,
+         4.97956834270742063578115693799423285e-02L,
+         4.90554345550297788875281653672381736e-02L,
+         4.81858617570871291407794922983045926e-02L,
+         4.71855465692991539452614781810994865e-02L,
+         4.60592382710069881162717355593735806e-02L,
+         4.48148001331626631923555516167232438e-02L,
+         4.34525397013560693168317281170732581e-02L,
+         4.19698102151642461471475412859697578e-02L,
+         4.03745389515359591119952797524681142e-02L,
+         3.86789456247275929503486515322810503e-02L,
+         3.68823646518212292239110656171359677e-02L,
+         3.49793380280600241374996707314678751e-02L,
+         3.29814470574837260318141910168539275e-02L,
+         3.09072575623877624728842529430922726e-02L,
+         2.87540487650412928439787853543342111e-02L,
+         2.65099548823331016106017093350754144e-02L,
+         2.41911620780806013656863707252320268e-02L,
+         2.18280358216091922971674857383389934e-02L,
+         1.94141411939423811734089510501284559e-02L,
+         1.69208891890532726275722894203220924e-02L,
+         1.43697295070458048124514324435800102e-02L,
+         1.18230152534963417422328988532505929e-02L,
+         9.27327965951776342844114689202436042e-03L,
+         6.63070391593129217331982636975016813e-03L,
+         3.89046112709988405126720184451550328e-03L,
+         1.38901369867700762455159122675969968e-03L,
+      };
+      return data;
+   }
+};
+
+#ifdef BOOST_HAS_FLOAT128
+template <class T>
+class gauss_kronrod_detail<T, 61, 3>
+{
+public:
+   static std::array<T, 31> const & abscissa()
+   {
+      static const std::array<T, 31> data = {
+         0.00000000000000000000000000000000000e+00Q,
+         5.14718425553176958330252131667225737e-02Q,
+         1.02806937966737030147096751318000592e-01Q,
+         1.53869913608583546963794672743255920e-01Q,
+         2.04525116682309891438957671002024710e-01Q,
+         2.54636926167889846439805129817805108e-01Q,
+         3.04073202273625077372677107199256554e-01Q,
+         3.52704725530878113471037207089373861e-01Q,
+         4.00401254830394392535476211542660634e-01Q,
+         4.47033769538089176780609900322854000e-01Q,
+         4.92480467861778574993693061207708796e-01Q,
+         5.36624148142019899264169793311072794e-01Q,
+         5.79345235826361691756024932172540496e-01Q,
+         6.20526182989242861140477556431189299e-01Q,
+         6.60061064126626961370053668149270753e-01Q,
+         6.97850494793315796932292388026640068e-01Q,
+         7.33790062453226804726171131369527646e-01Q,
+         7.67777432104826194917977340974503132e-01Q,
+         7.99727835821839083013668942322683241e-01Q,
+         8.29565762382768397442898119732501916e-01Q,
+         8.57205233546061098958658510658943857e-01Q,
+         8.82560535792052681543116462530225590e-01Q,
+         9.05573307699907798546522558925958320e-01Q,
+         9.26200047429274325879324277080474004e-01Q,
+         9.44374444748559979415831324037439122e-01Q,
+         9.60021864968307512216871025581797663e-01Q,
+         9.73116322501126268374693868423706885e-01Q,
+         9.83668123279747209970032581605662802e-01Q,
+         9.91630996870404594858628366109485725e-01Q,
+         9.96893484074649540271630050918695283e-01Q,
+         9.99484410050490637571325895705810819e-01Q,
+      };
+      return data;
+   }
+   static std::array<T, 31> const & weights()
+   {
+      static const std::array<T, 31> data = {
+         5.14947294294515675583404336470993075e-02Q,
+         5.14261285374590259338628792157812598e-02Q,
+         5.12215478492587721706562826049442083e-02Q,
+         5.08817958987496064922974730498046919e-02Q,
+         5.04059214027823468408930856535850289e-02Q,
+         4.97956834270742063578115693799423285e-02Q,
+         4.90554345550297788875281653672381736e-02Q,
+         4.81858617570871291407794922983045926e-02Q,
+         4.71855465692991539452614781810994865e-02Q,
+         4.60592382710069881162717355593735806e-02Q,
+         4.48148001331626631923555516167232438e-02Q,
+         4.34525397013560693168317281170732581e-02Q,
+         4.19698102151642461471475412859697578e-02Q,
+         4.03745389515359591119952797524681142e-02Q,
+         3.86789456247275929503486515322810503e-02Q,
+         3.68823646518212292239110656171359677e-02Q,
+         3.49793380280600241374996707314678751e-02Q,
+         3.29814470574837260318141910168539275e-02Q,
+         3.09072575623877624728842529430922726e-02Q,
+         2.87540487650412928439787853543342111e-02Q,
+         2.65099548823331016106017093350754144e-02Q,
+         2.41911620780806013656863707252320268e-02Q,
+         2.18280358216091922971674857383389934e-02Q,
+         1.94141411939423811734089510501284559e-02Q,
+         1.69208891890532726275722894203220924e-02Q,
+         1.43697295070458048124514324435800102e-02Q,
+         1.18230152534963417422328988532505929e-02Q,
+         9.27327965951776342844114689202436042e-03Q,
+         6.63070391593129217331982636975016813e-03Q,
+         3.89046112709988405126720184451550328e-03Q,
+         1.38901369867700762455159122675969968e-03Q,
+      };
+      return data;
+   }
+};
+#endif
+
+template <class T>
+class gauss_kronrod_detail<T, 61, 4>
+{
+public:
+   static  std::array<T, 31> const & abscissa()
+   {
+      static  std::array<T, 31> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1471842555317695833025213166722573749141453666569564255160843987964755210427109055870090707285485841217089963590678e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0280693796673703014709675131800059247190133296515840552101946914632788253917872738234797140786490207720254922664913e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.5386991360858354696379467274325592041855197124433846171896298291578714851081610139692310651074078557990111754952062e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0452511668230989143895767100202470952410426459556377447604465028350321894663245495592565235317147819577892124850607e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.5463692616788984643980512981780510788278930330251842616428597508896353156907880290636628138423620257595521678255758e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0407320227362507737267710719925655353115778980946272844421536998312150442387767304001423699909778588529370119457430e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.5270472553087811347103720708937386065363100802142562659418446890026941623319107866436039675211352945165817827083104e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0040125483039439253547621154266063361104593297078395983186610656429170689311759061175527015710247383961903284673474e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.4703376953808917678060990032285400016240759386142440975447738172761535172858420700400688872124189834257262048739699e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.9248046786177857499369306120770879564426564096318697026073340982988422546396352776837047452262025983265531109327026e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.3662414814201989926416979331107279416417800693029710545274348291201490861897837863114116009718990258091585830703557e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7934523582636169175602493217254049590705158881215289208126016612312833567812241903809970751783808208940322061083509e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2052618298924286114047755643118929920736469282952813259505117012433531497488911774115258445532782106478789996137481e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.6006106412662696137005366814927075303835037480883390955067197339904937499734522076788020517029688190998858739703079e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.9785049479331579693229238802664006838235380065395465637972284673997672124315996069538163644008904690545069439941341e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.3379006245322680472617113136952764566938172775468549208701399518300016463613325382024664531597318795933262446521430e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6777743210482619491797734097450313169488361723290845320649438736515857017299504505260960258623968420224697596501719e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 7.9972783582183908301366894232268324073569842937778450923647349548686662567326007229195202524185356472023967927713548e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.2956576238276839744289811973250191643906869617034167880695298345365650658958163508295244350814016004371545455777732e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.5720523354606109895865851065894385682080017062359612850504551739119887225712932688031120704657195642614071367390794e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 8.8256053579205268154311646253022559005668914714648423206832605312161626269519165572921583828573210485349058106849548e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.0557330769990779854652255892595831956897536366222841356404766397803760239449631913585074426842574155323901785046522e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.2620004742927432587932427708047400408647453682532906091103713367942299565110232681677288015055886244486106298320068e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4437444474855997941583132403743912158564371496498093181748940139520917000657342753448871376849848523800667868447591e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6002186496830751221687102558179766293035921740392339948566167242493995770706842922718944370380002378239172677454384e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.7311632250112626837469386842370688488763796428343933853755850185624118958166838288308561708261486365954975485787212e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8366812327974720997003258160566280194031785470971136351718001015114429536479104370207597166035471368057762560137209e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9163099687040459485862836610948572485050033374616325510019923349807489603260796605556191495843575227494654783755353e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9689348407464954027163005091869528334088203811775079010809429780238769521016374081588201955806171741257405095963817e-01),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9948441005049063757132589570581081946887394701850801923632642830748016674843587830656468823145435723317885056396548e-01),
+      };
+      return data;
+   }
+   static  std::array<T, 31> const & weights()
+   {
+      static  std::array<T, 31> data = {
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1494729429451567558340433647099307532736880396464168074637323362474083844397567724480716864880173808112573901197920e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1426128537459025933862879215781259829552034862395987263855824172761589259406892072066110681184224608133314131500422e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1221547849258772170656282604944208251146952425246327553509056805511015401279553971190412722969308620984161625812560e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.0881795898749606492297473049804691853384914260919239920771942080972542646780575571132056254070929858650733836163479e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 5.0405921402782346840893085653585028902197018251622233664243959211066713308635283713447747907973700791599900911248852e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.9795683427074206357811569379942328539209602813696108951047392842948482646220377655098341924089250200477846596263918e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.9055434555029778887528165367238173605887405295296569579490717901328215644590555247522873065246297467067324397612445e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.8185861757087129140779492298304592605799236108429800057373350872433793583969368428942672063270298939865425225579922e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.7185546569299153945261478181099486482884807300628457194141861551725533289490897029020276525603515502104799540544222e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.6059238271006988116271735559373580594692875571824924004732379492293604006446052672252973438978639166425766841417488e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.4814800133162663192355551616723243757431392796373009889680201194063503947907899189061064792111919040540351834527742e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.3452539701356069316831728117073258074603308631703168064888805495738640839573863333942084117196541456054957383622173e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.1969810215164246147147541285969757790088656718992374820388720323852655511200365790379948462006156953358103259681948e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0374538951535959111995279752468114216126062126030255633998289613810846761059740961836828802959573901107306640876603e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.8678945624727592950348651532281050250923629821553846790376130679337402056620700554139109487533759557982632153728099e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.6882364651821229223911065617135967736955164781030337670005198584196134970154169862584193360751243227989492571664973e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.4979338028060024137499670731467875097226912794818719972208457232177786702008744219498470603846784465175225933802357e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.2981447057483726031814191016853927510599291213858385714519347641452316582381008804994515341969205985818543200837577e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0907257562387762472884252943092272635270458523807153426840486964022086189874056947717446328187131273807982629114591e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.8754048765041292843978785354334211144679160542074930035102280759132174815469834227854660515366003136772757344886331e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.6509954882333101610601709335075414366517579522748565770867438338472138903658077617652522759934474895733739329287706e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.4191162078080601365686370725232026760391377828182462432228943562944885267501070688006470962871743661192935455117297e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 2.1828035821609192297167485738338993401507296056834912773630422358720439403382559079356058602393879803560534375378340e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.9414141193942381173408951050128455851421014191431525770276066536497179079025540486072726114628763606440143557769099e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.6920889189053272627572289420322092368566703783835191139883410840546679978551861043620089451681146020853650713611444e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4369729507045804812451432443580010195841899895001505873565899403000198662495821906144274682894222591414503342336172e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1823015253496341742232898853250592896264406250607818326302431548265365155855182739401700032519141448997853772603766e-02),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 9.2732796595177634284411468920243604212700249381931076964956469143626665557434385492325784596343112153704094886248672e-03),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 6.6307039159312921733198263697501681336283882177812585973955597357837568277731921327731815844512598157843672104469554e-03),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 3.8904611270998840512672018445155032785151429848864649214200101281144733676455451061226273655941038347210163533085954e-03),
+         BOOST_MATH_HUGE_CONSTANT(T, 0, 1.3890136986770076245515912267596996810488412919632724534411055332301367130989865366956251556423820479579333920310978e-03),
+      };
+      return data;
+   }
+};
+
+}
+
+template <class Real, unsigned N, class Policy = boost::math::policies::policy<> >
+class gauss_kronrod : public detail::gauss_kronrod_detail<Real, N, detail::gauss_constant_category<Real>::value>
+{
+   typedef detail::gauss_kronrod_detail<Real, N, detail::gauss_constant_category<Real>::value> base;
+public:
+  typedef Real value_type;
+private:
+   template <class F>
+   static auto integrate_non_adaptive_m1_1(F f, Real* error = nullptr, Real* pL1 = nullptr)->decltype(std::declval<F>()(std::declval<Real>()))
+   {
+      typedef decltype(f(Real(0))) K;
+      using std::abs;
+      unsigned gauss_start = 2;
+      unsigned kronrod_start = 1;
+      unsigned gauss_order = (N - 1) / 2;
+      K kronrod_result = 0;
+      K gauss_result = 0;
+      K fp, fm;
+      if (gauss_order & 1)
+      {
+         fp = f(value_type(0));
+         kronrod_result = fp * base::weights()[0];
+         gauss_result += fp * gauss<Real, (N - 1) / 2>::weights()[0];
+      }
+      else
+      {
+         fp = f(value_type(0));
+         kronrod_result = fp * base::weights()[0];
+         gauss_start = 1;
+         kronrod_start = 2;
+      }
+      Real L1 = abs(kronrod_result);
+      for (unsigned i = gauss_start; i < base::abscissa().size(); i += 2)
+      {
+         fp = f(base::abscissa()[i]);
+         fm = f(-base::abscissa()[i]);
+         kronrod_result += (fp + fm) * base::weights()[i];
+         L1 += (abs(fp) + abs(fm)) *  base::weights()[i];
+         gauss_result += (fp + fm) * gauss<Real, (N - 1) / 2>::weights()[i / 2];
+      }
+      for (unsigned i = kronrod_start; i < base::abscissa().size(); i += 2)
+      {
+         fp = f(base::abscissa()[i]);
+         fm = f(-base::abscissa()[i]);
+         kronrod_result += (fp + fm) * base::weights()[i];
+         L1 += (abs(fp) + abs(fm)) *  base::weights()[i];
+      }
+      if (pL1)
+         *pL1 = L1;
+      if (error)
+         *error = (std::max)(static_cast<Real>(abs(kronrod_result - gauss_result)), static_cast<Real>(abs(kronrod_result * tools::epsilon<Real>() * Real(2))));
+      return kronrod_result;
+   }
+
+   template <class F>
+   struct recursive_info
+   {
+      F f;
+      Real tol;
+   };
+
+   template <class F>
+   static auto recursive_adaptive_integrate(const recursive_info<F>* info, Real a, Real b, unsigned max_levels, Real abs_tol, Real* error, Real* L1)->decltype(std::declval<F>()(std::declval<Real>()))
+   {
+      typedef decltype(info->f(Real(a))) K;
+      using std::abs;
+      Real error_local;
+      Real mean = (b + a) / 2;
+      Real scale = (b - a) / 2;
+      auto ff = [&](const Real& x)->K
+      {
+         return info->f(scale * x + mean);
+      };
+      K r1 = integrate_non_adaptive_m1_1(ff, &error_local, L1);
+      K estimate = scale * r1;
+
+      K tmp = estimate * info->tol;
+      Real abs_tol1 = abs(tmp);
+      if (abs_tol == 0)
+         abs_tol = abs_tol1;
+
+      if (max_levels && (abs_tol1 < error_local) && (abs_tol < error_local))
+      {
+         Real mid = (a + b) / 2;
+         Real L1_local;
+         estimate = recursive_adaptive_integrate(info, a, mid, max_levels - 1, abs_tol / 2, error, L1);
+         estimate += recursive_adaptive_integrate(info, mid, b, max_levels - 1, abs_tol / 2, &error_local, &L1_local);
+         if (error)
+            *error += error_local;
+         if (L1)
+            *L1 += L1_local;
+         return estimate;
+      }
+      if(L1)
+         *L1 *= scale;
+      if (error)
+         *error = error_local;
+      return estimate;
+   }
+
+public:
+   template <class F>
+   static auto integrate(F f, Real a, Real b, unsigned max_depth = 15, Real tol = tools::root_epsilon<Real>(), Real* error = nullptr, Real* pL1 = nullptr)->decltype(std::declval<F>()(std::declval<Real>()))
+   {
+      typedef decltype(f(a)) K;
+      static const char* function = "boost::math::quadrature::gauss_kronrod<%1%>::integrate(f, %1%, %1%)";
+      if (!(boost::math::isnan)(a) && !(boost::math::isnan)(b))
+      {
+         // Infinite limits:
+         if ((a <= -tools::max_value<Real>()) && (b >= tools::max_value<Real>()))
+         {
+            auto u = [&](const Real& t)->K
+            {
+               Real t_sq = t*t;
+               Real inv = 1 / (1 - t_sq);
+               Real w = (1 + t_sq)*inv*inv;
+               Real arg = t*inv;
+               K res = f(arg)*w;
+               return res;
+            };
+            recursive_info<decltype(u)> info = { u, tol };
+            K res = recursive_adaptive_integrate(&info, Real(-1), Real(1), max_depth, Real(0), error, pL1);
+            return res;
+         }
+
+         // Right limit is infinite:
+         if ((boost::math::isfinite)(a) && (b >= tools::max_value<Real>()))
+         {
+            auto u = [&](const Real& t)->K
+            {
+               Real z = 1 / (t + 1);
+               Real arg = 2 * z + a - 1;
+               K res = f(arg)*z*z;
+               return res;
+            };
+            recursive_info<decltype(u)> info = { u, tol };
+            K Q = Real(2) * recursive_adaptive_integrate(&info, Real(-1), Real(1), max_depth, Real(0), error, pL1);
+            if (pL1)
+            {
+               *pL1 *= 2;
+            }
+            return Q;
+         }
+
+         if ((boost::math::isfinite)(b) && (a <= -tools::max_value<Real>()))
+         {
+            auto v = [&](const Real& t)->K
+            {
+               Real z = 1 / (t + 1);
+               Real arg = 2 * z - 1;
+               return f(b - arg) * z * z;
+            };
+            recursive_info<decltype(v)> info = { v, tol };
+            K Q = Real(2) * recursive_adaptive_integrate(&info, Real(-1), Real(1), max_depth, Real(0), error, pL1);
+            if (pL1)
+            {
+               *pL1 *= 2;
+            }
+            return Q;
+         }
+
+         if ((boost::math::isfinite)(a) && (boost::math::isfinite)(b))
+         {
+            if (a==b)
+            {
+               return K(0);
+            }
+            recursive_info<F> info = { f, tol };
+            if (b < a)
+            {
+               return -recursive_adaptive_integrate(&info, b, a, max_depth, Real(0), error, pL1);
+            }
+            return recursive_adaptive_integrate(&info, a, b, max_depth, Real(0), error, pL1);
+         }
+      }
+      return static_cast<K>(policies::raise_domain_error(function, "The domain of integration is not sensible; please check the bounds.", a, Policy()));
+   }
+};
+
+} // namespace quadrature
+} // namespace math
+} // namespace boost
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // BOOST_MATH_QUADRATURE_GAUSS_KRONROD_HPP
diff --git a/ThirdParty/boost/math/special_functions/bernoulli.hpp b/ThirdParty/boost/math/special_functions/bernoulli.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..22a4bca3bdfdfafb37628d4cc578f0b08748edc1
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/bernoulli.hpp
@@ -0,0 +1,143 @@
+
+///////////////////////////////////////////////////////////////////////////////
+//  Copyright 2013 Nikhar Agrawal
+//  Copyright 2013 Christopher Kormanyos
+//  Copyright 2013 John Maddock
+//  Copyright 2013 Paul Bristow
+//  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_BERNOULLI_B2N_2013_05_30_HPP_
+#define _BOOST_BERNOULLI_B2N_2013_05_30_HPP_
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/special_functions/detail/unchecked_bernoulli.hpp>
+#include <boost/math/special_functions/detail/bernoulli_details.hpp>
+
+namespace boost { namespace math { 
+   
+namespace detail {
+
+template <class T, class OutputIterator, class Policy, int N>
+OutputIterator bernoulli_number_imp(OutputIterator out, std::size_t start, std::size_t n, const Policy& pol, const boost::integral_constant<int, N>& tag)
+{
+   for(std::size_t i = start; (i <= max_bernoulli_b2n<T>::value) && (i < start + n); ++i)
+   {
+      *out = unchecked_bernoulli_imp<T>(i, tag);
+      ++out;
+   }
+   
+   for(std::size_t i = (std::max)(static_cast<std::size_t>(max_bernoulli_b2n<T>::value + 1), start); i < start + n; ++i)
+   {
+      // We must overflow:
+      *out = (i & 1 ? 1 : -1) * policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(n)", 0, T(i), pol);
+      ++out;
+   }
+   return out;
+}
+
+template <class T, class OutputIterator, class Policy>
+OutputIterator bernoulli_number_imp(OutputIterator out, std::size_t start, std::size_t n, const Policy& pol, const boost::integral_constant<int, 0>& tag)
+{
+   for(std::size_t i = start; (i <= max_bernoulli_b2n<T>::value) && (i < start + n); ++i)
+   {
+      *out = unchecked_bernoulli_imp<T>(i, tag);
+      ++out;
+   }
+   //
+   // Short circuit return so we don't grab the mutex below unless we have to:
+   //
+   if(start + n <= max_bernoulli_b2n<T>::value)
+      return out;
+
+   return get_bernoulli_numbers_cache<T, Policy>().copy_bernoulli_numbers(out, start, n, pol);
+}
+
+} // namespace detail
+
+template <class T, class Policy>
+inline T bernoulli_b2n(const int i, const Policy &pol)
+{
+   typedef boost::integral_constant<int, detail::bernoulli_imp_variant<T>::value> tag_type;
+   if(i < 0)
+      return policies::raise_domain_error<T>("boost::math::bernoulli_b2n<%1%>", "Index should be >= 0 but got %1%", T(i), pol);
+
+   T result = static_cast<T>(0); // The = 0 is just to silence compiler warnings :-(
+   boost::math::detail::bernoulli_number_imp<T>(&result, static_cast<std::size_t>(i), 1u, pol, tag_type());
+   return result;
+}
+
+template <class T>
+inline T bernoulli_b2n(const int i)
+{
+   return boost::math::bernoulli_b2n<T>(i, policies::policy<>());
+}
+
+template <class T, class OutputIterator, class Policy>
+inline OutputIterator bernoulli_b2n(const int start_index,
+                                    const unsigned number_of_bernoullis_b2n,
+                                    OutputIterator out_it,
+                                    const Policy& pol)
+{
+   typedef boost::integral_constant<int, detail::bernoulli_imp_variant<T>::value> tag_type;
+   if(start_index < 0)
+   {
+      *out_it = policies::raise_domain_error<T>("boost::math::bernoulli_b2n<%1%>", "Index should be >= 0 but got %1%", T(start_index), pol);
+      return ++out_it;
+   }
+
+   return boost::math::detail::bernoulli_number_imp<T>(out_it, start_index, number_of_bernoullis_b2n, pol, tag_type());
+}
+
+template <class T, class OutputIterator>
+inline OutputIterator bernoulli_b2n(const int start_index,
+                                    const unsigned number_of_bernoullis_b2n,
+                                    OutputIterator out_it)
+{
+   return boost::math::bernoulli_b2n<T, OutputIterator>(start_index, number_of_bernoullis_b2n, out_it, policies::policy<>());
+}
+
+template <class T, class Policy>
+inline T tangent_t2n(const int i, const Policy &pol)
+{
+   if(i < 0)
+      return policies::raise_domain_error<T>("boost::math::tangent_t2n<%1%>", "Index should be >= 0 but got %1%", T(i), pol);
+
+   T result;
+   boost::math::detail::get_bernoulli_numbers_cache<T, Policy>().copy_tangent_numbers(&result, i, 1, pol);
+   return result;
+}
+
+template <class T>
+inline T tangent_t2n(const int i)
+{
+   return boost::math::tangent_t2n<T>(i, policies::policy<>());
+}
+
+template <class T, class OutputIterator, class Policy>
+inline OutputIterator tangent_t2n(const int start_index,
+                                    const unsigned number_of_tangent_t2n,
+                                    OutputIterator out_it,
+                                    const Policy& pol)
+{
+   if(start_index < 0)
+   {
+      *out_it = policies::raise_domain_error<T>("boost::math::tangent_t2n<%1%>", "Index should be >= 0 but got %1%", T(start_index), pol);
+      return ++out_it;
+   }
+
+   return boost::math::detail::get_bernoulli_numbers_cache<T, Policy>().copy_tangent_numbers(out_it, start_index, number_of_tangent_t2n, pol);
+}
+
+template <class T, class OutputIterator>
+inline OutputIterator tangent_t2n(const int start_index,
+                                    const unsigned number_of_tangent_t2n,
+                                    OutputIterator out_it)
+{
+   return boost::math::tangent_t2n<T, OutputIterator>(start_index, number_of_tangent_t2n, out_it, policies::policy<>());
+}
+
+} } // namespace boost::math
+
+#endif // _BOOST_BERNOULLI_B2N_2013_05_30_HPP_
diff --git a/ThirdParty/boost/math/special_functions/cos_pi.hpp b/ThirdParty/boost/math/special_functions/cos_pi.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c565ac08bfd046561e4994c6a701235e9f2b263d
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/cos_pi.hpp
@@ -0,0 +1,85 @@
+//  Copyright (c) 2007 John Maddock
+//  Use, modification and distribution are subject to 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_COS_PI_HPP
+#define BOOST_MATH_COS_PI_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/math/tools/config.hpp>
+#include <boost/math/special_functions/trunc.hpp>
+#include <boost/math/tools/promotion.hpp>
+#include <boost/math/constants/constants.hpp>
+
+namespace boost{ namespace math{ namespace detail{
+
+template <class T, class Policy>
+T cos_pi_imp(T x, const Policy& pol)
+{
+   BOOST_MATH_STD_USING // ADL of std names
+   // cos of pi*x:
+   bool invert = false;
+   if(fabs(x) < 0.25)
+      return cos(constants::pi<T>() * x);
+
+   if(x < 0)
+   {
+      x = -x;
+   }
+   T rem = floor(x);
+   if(iconvert(rem, pol) & 1)
+      invert = !invert;
+   rem = x - rem;
+   if(rem > 0.5f)
+   {
+      rem = 1 - rem;
+      invert = !invert;
+   }
+   if(rem == 0.5f)
+      return 0;
+   
+   if(rem > 0.25f)
+   {
+      rem = 0.5f - rem;
+      rem = sin(constants::pi<T>() * rem);
+   }
+   else
+      rem = cos(constants::pi<T>() * rem);
+   return invert ? T(-rem) : rem;
+}
+
+} // namespace detail
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type cos_pi(T x, const Policy&)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   typedef typename policies::normalise<
+      Policy,
+      policies::promote_float<false>,
+      policies::promote_double<false>,
+      policies::discrete_quantile<>,
+      policies::assert_undefined<>,
+      // We want to ignore overflows since the result is in [-1,1] and the 
+      // check slows the code down considerably.
+      policies::overflow_error<policies::ignore_error> >::type forwarding_policy;
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(boost::math::detail::cos_pi_imp<value_type>(x, forwarding_policy()), "cos_pi");
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type cos_pi(T x)
+{
+   return boost::math::cos_pi(x, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+#endif
+
diff --git a/ThirdParty/boost/math/special_functions/detail/bernoulli_details.hpp b/ThirdParty/boost/math/special_functions/detail/bernoulli_details.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4ab3e557c5895cc22537dfeced4dfa6e4f31763d
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/detail/bernoulli_details.hpp
@@ -0,0 +1,673 @@
+///////////////////////////////////////////////////////////////////////////////
+//  Copyright 2013 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_BERNOULLI_DETAIL_HPP
+#define BOOST_MATH_BERNOULLI_DETAIL_HPP
+
+#include <boost/config.hpp>
+#include <boost/detail/lightweight_mutex.hpp>
+#include <boost/math/tools/atomic.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/math/tools/toms748_solve.hpp>
+#include <boost/math/tools/cxx03_warn.hpp>
+#include <vector>
+
+namespace boost{ namespace math{ namespace detail{
+//
+// Asymptotic expansion for B2n due to
+// Luschny LogB3 formula (http://www.luschny.de/math/primes/bernincl.html)
+//
+template <class T, class Policy>
+T b2n_asymptotic(int n)
+{
+   BOOST_MATH_STD_USING
+   const T nx = static_cast<T>(n);
+   const T nx2(nx * nx);
+
+   const T approximate_log_of_bernoulli_bn = 
+        ((boost::math::constants::half<T>() + nx) * log(nx))
+        + ((boost::math::constants::half<T>() - nx) * log(boost::math::constants::pi<T>()))
+        + (((T(3) / 2) - nx) * boost::math::constants::ln_two<T>())
+        + ((nx * (T(2) - (nx2 * 7) * (1 + ((nx2 * 30) * ((nx2 * 12) - 1))))) / (((nx2 * nx2) * nx2) * 2520));
+   return ((n / 2) & 1 ? 1 : -1) * (approximate_log_of_bernoulli_bn > tools::log_max_value<T>() 
+      ? policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, nx, Policy())
+      : static_cast<T>(exp(approximate_log_of_bernoulli_bn)));
+}
+
+template <class T, class Policy>
+T t2n_asymptotic(int n)
+{
+   BOOST_MATH_STD_USING
+   // Just get B2n and convert to a Tangent number:
+   T t2n = fabs(b2n_asymptotic<T, Policy>(2 * n)) / (2 * n);
+   T p2 = ldexp(T(1), n);
+   if(tools::max_value<T>() / p2 < t2n)
+      return policies::raise_overflow_error<T>("boost::math::tangent_t2n<%1%>(std::size_t)", 0, T(n), Policy());
+   t2n *= p2;
+   p2 -= 1;
+   if(tools::max_value<T>() / p2 < t2n)
+      return policies::raise_overflow_error<T>("boost::math::tangent_t2n<%1%>(std::size_t)", 0, Policy());
+   t2n *= p2;
+   return t2n;
+}
+//
+// We need to know the approximate value of /n/ which will
+// cause bernoulli_b2n<T>(n) to return infinity - this allows
+// us to elude a great deal of runtime checking for values below
+// n, and only perform the full overflow checks when we know that we're
+// getting close to the point where our calculations will overflow.
+// We use Luschny's LogB3 formula (http://www.luschny.de/math/primes/bernincl.html) 
+// to find the limit, and since we're dealing with the log of the Bernoulli numbers
+// we need only perform the calculation at double precision and not with T
+// (which may be a multiprecision type).  The limit returned is within 1 of the true
+// limit for all the types tested.  Note that although the code below is basically
+// the same as b2n_asymptotic above, it has been recast as a continuous real-valued 
+// function as this makes the root finding go smoother/faster.  It also omits the
+// sign of the Bernoulli number.
+//
+struct max_bernoulli_root_functor
+{
+   max_bernoulli_root_functor(ulong_long_type t) : target(static_cast<double>(t)) {}
+   double operator()(double n)
+   {
+      BOOST_MATH_STD_USING
+
+      // Luschny LogB3(n) formula.
+
+      const double nx2(n * n);
+
+      const double approximate_log_of_bernoulli_bn
+         =   ((boost::math::constants::half<double>() + n) * log(n))
+           + ((boost::math::constants::half<double>() - n) * log(boost::math::constants::pi<double>()))
+           + (((double(3) / 2) - n) * boost::math::constants::ln_two<double>())
+           + ((n * (2 - (nx2 * 7) * (1 + ((nx2 * 30) * ((nx2 * 12) - 1))))) / (((nx2 * nx2) * nx2) * 2520));
+
+      return approximate_log_of_bernoulli_bn - target;
+   }
+private:
+   double target;
+};
+
+template <class T, class Policy>
+inline std::size_t find_bernoulli_overflow_limit(const boost::false_type&)
+{
+   // Set a limit on how large the result can ever be:
+   static const double max_result = static_cast<double>((std::numeric_limits<std::size_t>::max)() - 1000u);
+
+   ulong_long_type t = lltrunc(boost::math::tools::log_max_value<T>());
+   max_bernoulli_root_functor fun(t);
+   boost::math::tools::equal_floor tol;
+   boost::uintmax_t max_iter = boost::math::policies::get_max_root_iterations<Policy>();
+   double result = boost::math::tools::toms748_solve(fun, sqrt(double(t)), double(t), tol, max_iter).first / 2;
+   if (result > max_result)
+      result = max_result;
+   
+   return static_cast<std::size_t>(result);
+}
+
+template <class T, class Policy>
+inline std::size_t find_bernoulli_overflow_limit(const boost::true_type&)
+{
+   return max_bernoulli_index<bernoulli_imp_variant<T>::value>::value;
+}
+
+template <class T, class Policy>
+std::size_t b2n_overflow_limit()
+{
+   // This routine is called at program startup if it's called at all:
+   // that guarantees safe initialization of the static variable.
+   typedef boost::integral_constant<bool, (bernoulli_imp_variant<T>::value >= 1) && (bernoulli_imp_variant<T>::value <= 3)> tag_type;
+   static const std::size_t lim = find_bernoulli_overflow_limit<T, Policy>(tag_type());
+   return lim;
+}
+
+//
+// The tangent numbers grow larger much more rapidly than the Bernoulli numbers do....
+// so to compute the Bernoulli numbers from the tangent numbers, we need to avoid spurious
+// overflow in the calculation, we can do this by scaling all the tangent number by some scale factor:
+//
+template <class T>
+inline typename enable_if_c<std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::radix == 2), T>::type tangent_scale_factor()
+{
+   BOOST_MATH_STD_USING
+   return ldexp(T(1), std::numeric_limits<T>::min_exponent + 5);
+}
+template <class T>
+inline typename disable_if_c<std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::radix == 2), T>::type tangent_scale_factor()
+{
+   return tools::min_value<T>() * 16;
+}
+//
+// Initializer: ensure all our constants are initialized prior to the first call of main:
+//
+template <class T, class Policy>
+struct bernoulli_initializer
+{
+   struct init
+   {
+      init()
+      {
+         //
+         // We call twice, once to initialize our static table, and once to
+         // initialize our dymanic table:
+         //
+         boost::math::bernoulli_b2n<T>(2, Policy());
+#ifndef BOOST_NO_EXCEPTIONS
+         try{
+#endif
+            boost::math::bernoulli_b2n<T>(max_bernoulli_b2n<T>::value + 1, Policy());
+#ifndef BOOST_NO_EXCEPTIONS
+         } catch(const std::overflow_error&){}
+#endif
+         boost::math::tangent_t2n<T>(2, Policy());
+      }
+      void force_instantiate()const{}
+   };
+   static const init initializer;
+   static void force_instantiate()
+   {
+      initializer.force_instantiate();
+   }
+};
+
+template <class T, class Policy>
+const typename bernoulli_initializer<T, Policy>::init bernoulli_initializer<T, Policy>::initializer;
+
+//
+// We need something to act as a cache for our calculated Bernoulli numbers.  In order to
+// ensure both fast access and thread safety, we need a stable table which may be extended
+// in size, but which never reallocates: that way values already calculated may be accessed
+// concurrently with another thread extending the table with new values.
+//
+// Very very simple vector class that will never allocate more than once, we could use
+// boost::container::static_vector here, but that allocates on the stack, which may well
+// cause issues for the amount of memory we want in the extreme case...
+//
+template <class T>
+struct fixed_vector : private std::allocator<T>
+{
+   typedef unsigned size_type;
+   typedef T* iterator;
+   typedef const T* const_iterator;
+   fixed_vector() : m_used(0)
+   { 
+      std::size_t overflow_limit = 5 + b2n_overflow_limit<T, policies::policy<> >();
+      m_capacity = static_cast<unsigned>((std::min)(overflow_limit, static_cast<std::size_t>(100000u)));
+      m_data = this->allocate(m_capacity); 
+   }
+   ~fixed_vector()
+   {
+#ifdef BOOST_NO_CXX11_ALLOCATOR
+      for(unsigned i = 0; i < m_used; ++i)
+         this->destroy(&m_data[i]);
+      this->deallocate(m_data, m_capacity);
+#else
+      typedef std::allocator<T> allocator_type;
+      typedef std::allocator_traits<allocator_type> allocator_traits; 
+      allocator_type& alloc = *this; 
+      for(unsigned i = 0; i < m_used; ++i)
+         allocator_traits::destroy(alloc, &m_data[i]);
+      allocator_traits::deallocate(alloc, m_data, m_capacity);
+#endif
+   }
+   T& operator[](unsigned n) { BOOST_ASSERT(n < m_used); return m_data[n]; }
+   const T& operator[](unsigned n)const { BOOST_ASSERT(n < m_used); return m_data[n]; }
+   unsigned size()const { return m_used; }
+   unsigned size() { return m_used; }
+   void resize(unsigned n, const T& val)
+   {
+      if(n > m_capacity)
+      {
+         BOOST_THROW_EXCEPTION(std::runtime_error("Exhausted storage for Bernoulli numbers."));
+      }
+      for(unsigned i = m_used; i < n; ++i)
+         new (m_data + i) T(val);
+      m_used = n;
+   }
+   void resize(unsigned n) { resize(n, T()); }
+   T* begin() { return m_data; }
+   T* end() { return m_data + m_used; }
+   T* begin()const { return m_data; }
+   T* end()const { return m_data + m_used; }
+   unsigned capacity()const { return m_capacity; }
+   void clear() { m_used = 0; }
+private:
+   T* m_data;
+   unsigned m_used, m_capacity;
+};
+
+template <class T, class Policy>
+class bernoulli_numbers_cache
+{
+public:
+   bernoulli_numbers_cache() : m_overflow_limit((std::numeric_limits<std::size_t>::max)())
+#if defined(BOOST_HAS_THREADS) && !defined(BOOST_MATH_NO_ATOMIC_INT)
+      , m_counter(0)
+#endif
+      , m_current_precision(boost::math::tools::digits<T>())
+   {}
+
+   typedef fixed_vector<T> container_type;
+
+   void tangent(std::size_t m)
+   {
+      static const std::size_t min_overflow_index = b2n_overflow_limit<T, Policy>() - 1;
+      tn.resize(static_cast<typename container_type::size_type>(m), T(0U));
+
+      BOOST_MATH_INSTRUMENT_VARIABLE(min_overflow_index);
+
+      std::size_t prev_size = m_intermediates.size();
+      m_intermediates.resize(m, T(0U));
+
+      if(prev_size == 0)
+      {
+         m_intermediates[1] = tangent_scale_factor<T>() /*T(1U)*/;
+         tn[0U] = T(0U);
+         tn[1U] = tangent_scale_factor<T>()/* T(1U)*/;
+         BOOST_MATH_INSTRUMENT_VARIABLE(tn[0]);
+         BOOST_MATH_INSTRUMENT_VARIABLE(tn[1]);
+      }
+
+      for(std::size_t i = std::max<size_t>(2, prev_size); i < m; i++)
+      {
+         bool overflow_check = false;
+         if(i >= min_overflow_index && (boost::math::tools::max_value<T>() / (i-1) < m_intermediates[1]) )
+         {
+            std::fill(tn.begin() + i, tn.end(), boost::math::tools::max_value<T>());
+            break;
+         }
+         m_intermediates[1] = m_intermediates[1] * (i-1);
+         for(std::size_t j = 2; j <= i; j++)
+         {
+            overflow_check =
+                  (i >= min_overflow_index) && (
+                  (boost::math::tools::max_value<T>() / (i - j) < m_intermediates[j])
+                  || (boost::math::tools::max_value<T>() / (i - j + 2) < m_intermediates[j-1])
+                  || (boost::math::tools::max_value<T>() - m_intermediates[j] * (i - j) < m_intermediates[j-1] * (i - j + 2))
+                  || ((boost::math::isinf)(m_intermediates[j]))
+                );
+
+            if(overflow_check)
+            {
+               std::fill(tn.begin() + i, tn.end(), boost::math::tools::max_value<T>());
+               break;
+            }
+            m_intermediates[j] = m_intermediates[j] * (i - j) + m_intermediates[j-1] * (i - j + 2);
+         }
+         if(overflow_check)
+            break; // already filled the tn...
+         tn[static_cast<typename container_type::size_type>(i)] = m_intermediates[i];
+         BOOST_MATH_INSTRUMENT_VARIABLE(i);
+         BOOST_MATH_INSTRUMENT_VARIABLE(tn[static_cast<typename container_type::size_type>(i)]);
+      }
+   }
+
+   void tangent_numbers_series(const std::size_t m)
+   {
+      BOOST_MATH_STD_USING
+      static const std::size_t min_overflow_index = b2n_overflow_limit<T, Policy>() - 1;
+
+      typename container_type::size_type old_size = bn.size();
+
+      tangent(m);
+      bn.resize(static_cast<typename container_type::size_type>(m));
+
+      if(!old_size)
+      {
+         bn[0] = 1;
+         old_size = 1;
+      }
+
+      T power_two(ldexp(T(1), static_cast<int>(2 * old_size)));
+
+      for(std::size_t i = old_size; i < m; i++)
+      {
+         T b(static_cast<T>(i * 2));
+         //
+         // Not only do we need to take care to avoid spurious over/under flow in
+         // the calculation, but we also need to avoid overflow altogether in case
+         // we're calculating with a type where "bad things" happen in that case:
+         //
+         b  = b / (power_two * tangent_scale_factor<T>());
+         b /= (power_two - 1);
+         bool overflow_check = (i >= min_overflow_index) && (tools::max_value<T>() / tn[static_cast<typename container_type::size_type>(i)] < b);
+         if(overflow_check)
+         {
+            m_overflow_limit = i;
+            while(i < m)
+            {
+               b = std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : tools::max_value<T>();
+               bn[static_cast<typename container_type::size_type>(i)] = ((i % 2U) ? b : T(-b));
+               ++i;
+            }
+            break;
+         }
+         else
+         {
+            b *= tn[static_cast<typename container_type::size_type>(i)];
+         }
+
+         power_two = ldexp(power_two, 2);
+
+         const bool b_neg = i % 2 == 0;
+
+         bn[static_cast<typename container_type::size_type>(i)] = ((!b_neg) ? b : T(-b));
+      }
+   }
+
+   template <class OutputIterator>
+   OutputIterator copy_bernoulli_numbers(OutputIterator out, std::size_t start, std::size_t n, const Policy& pol)
+   {
+      //
+      // There are basically 3 thread safety options:
+      //
+      // 1) There are no threads (BOOST_HAS_THREADS is not defined).
+      // 2) There are threads, but we do not have a true atomic integer type, 
+      //    in this case we just use a mutex to guard against race conditions.
+      // 3) There are threads, and we have an atomic integer: in this case we can
+      //    use the double-checked locking pattern to avoid thread synchronisation
+      //    when accessing values already in the cache.
+      //
+      // First off handle the common case for overflow and/or asymptotic expansion:
+      //
+      if(start + n > bn.capacity())
+      {
+         if(start < bn.capacity())
+         {
+            out = copy_bernoulli_numbers(out, start, bn.capacity() - start, pol);
+            n -= bn.capacity() - start;
+            start = static_cast<std::size_t>(bn.capacity());
+         }
+         if(start < b2n_overflow_limit<T, Policy>() + 2u)
+         {
+            for(; n; ++start, --n)
+            {
+               *out = b2n_asymptotic<T, Policy>(static_cast<typename container_type::size_type>(start * 2U));
+               ++out;
+            }
+         }
+         for(; n; ++start, --n)
+         {
+            *out = policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(start), pol);
+            ++out;
+         }
+         return out;
+      }
+   #if !defined(BOOST_HAS_THREADS)
+      //
+      // Single threaded code, very simple:
+      //
+      if(m_current_precision < boost::math::tools::digits<T>())
+      {
+         bn.clear();
+         tn.clear();
+         m_intermediates.clear();
+         m_current_precision = boost::math::tools::digits<T>();
+      }
+      if(start + n >= bn.size())
+      {
+         std::size_t new_size = (std::min)((std::max)((std::max)(std::size_t(start + n), std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity()));
+         tangent_numbers_series(new_size);
+      }
+
+      for(std::size_t i = (std::max)(std::size_t(max_bernoulli_b2n<T>::value + 1), start); i < start + n; ++i)
+      {
+         *out = (i >= m_overflow_limit) ? policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol) : bn[i];
+         ++out;
+      }
+   #elif defined(BOOST_MATH_NO_ATOMIC_INT)
+      //
+      // We need to grab a mutex every time we get here, for both readers and writers:
+      //
+      boost::detail::lightweight_mutex::scoped_lock l(m_mutex);
+      if(m_current_precision < boost::math::tools::digits<T>())
+      {
+         bn.clear();
+         tn.clear();
+         m_intermediates.clear();
+         m_current_precision = boost::math::tools::digits<T>();
+      }
+      if(start + n >= bn.size())
+      {
+         std::size_t new_size = (std::min)((std::max)((std::max)(std::size_t(start + n), std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity()));
+         tangent_numbers_series(new_size);
+      }
+
+      for(std::size_t i = (std::max)(std::size_t(max_bernoulli_b2n<T>::value + 1), start); i < start + n; ++i)
+      {
+         *out = (i >= m_overflow_limit) ? policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol) : bn[i];
+         ++out;
+      }
+
+   #else
+      //
+      // Double-checked locking pattern, lets us access cached already cached values
+      // without locking:
+      //
+      // Get the counter and see if we need to calculate more constants:
+      //
+      if((static_cast<std::size_t>(m_counter.load(BOOST_MATH_ATOMIC_NS::memory_order_consume)) < start + n)
+         || (static_cast<int>(m_current_precision.load(BOOST_MATH_ATOMIC_NS::memory_order_consume)) < boost::math::tools::digits<T>()))
+      {
+         boost::detail::lightweight_mutex::scoped_lock l(m_mutex);
+
+         if((static_cast<std::size_t>(m_counter.load(BOOST_MATH_ATOMIC_NS::memory_order_consume)) < start + n)
+            || (static_cast<int>(m_current_precision.load(BOOST_MATH_ATOMIC_NS::memory_order_consume)) < boost::math::tools::digits<T>()))
+         {
+            if(static_cast<int>(m_current_precision.load(BOOST_MATH_ATOMIC_NS::memory_order_consume)) < boost::math::tools::digits<T>())
+            {
+               bn.clear();
+               tn.clear();
+               m_intermediates.clear();
+               m_counter.store(0, BOOST_MATH_ATOMIC_NS::memory_order_release);
+               m_current_precision = boost::math::tools::digits<T>();
+            }
+            if(start + n >= bn.size())
+            {
+               std::size_t new_size = (std::min)((std::max)((std::max)(std::size_t(start + n), std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity()));
+               tangent_numbers_series(new_size);
+            }
+            m_counter.store(static_cast<atomic_integer_type>(bn.size()), BOOST_MATH_ATOMIC_NS::memory_order_release);
+         }
+      }
+
+      for(std::size_t i = (std::max)(static_cast<std::size_t>(max_bernoulli_b2n<T>::value + 1), start); i < start + n; ++i)
+      {
+         *out = (i >= m_overflow_limit) ? policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol) : bn[static_cast<typename container_type::size_type>(i)];
+         ++out;
+      }
+
+   #endif
+      return out;
+   }
+
+   template <class OutputIterator>
+   OutputIterator copy_tangent_numbers(OutputIterator out, std::size_t start, std::size_t n, const Policy& pol)
+   {
+      //
+      // There are basically 3 thread safety options:
+      //
+      // 1) There are no threads (BOOST_HAS_THREADS is not defined).
+      // 2) There are threads, but we do not have a true atomic integer type, 
+      //    in this case we just use a mutex to guard against race conditions.
+      // 3) There are threads, and we have an atomic integer: in this case we can
+      //    use the double-checked locking pattern to avoid thread synchronisation
+      //    when accessing values already in the cache.
+      //
+      //
+      // First off handle the common case for overflow and/or asymptotic expansion:
+      //
+      if(start + n > bn.capacity())
+      {
+         if(start < bn.capacity())
+         {
+            out = copy_tangent_numbers(out, start, bn.capacity() - start, pol);
+            n -= bn.capacity() - start;
+            start = static_cast<std::size_t>(bn.capacity());
+         }
+         if(start < b2n_overflow_limit<T, Policy>() + 2u)
+         {
+            for(; n; ++start, --n)
+            {
+               *out = t2n_asymptotic<T, Policy>(static_cast<typename container_type::size_type>(start));
+               ++out;
+            }
+         }
+         for(; n; ++start, --n)
+         {
+            *out = policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(start), pol);
+            ++out;
+         }
+         return out;
+      }
+   #if !defined(BOOST_HAS_THREADS)
+      //
+      // Single threaded code, very simple:
+      //
+      if(m_current_precision < boost::math::tools::digits<T>())
+      {
+         bn.clear();
+         tn.clear();
+         m_intermediates.clear();
+         m_current_precision = boost::math::tools::digits<T>();
+      }
+      if(start + n >= bn.size())
+      {
+         std::size_t new_size = (std::min)((std::max)((std::max)(start + n, std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity()));
+         tangent_numbers_series(new_size);
+      }
+
+      for(std::size_t i = start; i < start + n; ++i)
+      {
+         if(i >= m_overflow_limit)
+            *out = policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol);
+         else
+         {
+            if(tools::max_value<T>() * tangent_scale_factor<T>() < tn[static_cast<typename container_type::size_type>(i)])
+               *out = policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol);
+            else
+               *out = tn[static_cast<typename container_type::size_type>(i)] / tangent_scale_factor<T>();
+         }
+         ++out;
+      }
+   #elif defined(BOOST_MATH_NO_ATOMIC_INT)
+      //
+      // We need to grab a mutex every time we get here, for both readers and writers:
+      //
+      boost::detail::lightweight_mutex::scoped_lock l(m_mutex);
+      if(m_current_precision < boost::math::tools::digits<T>())
+      {
+         bn.clear();
+         tn.clear();
+         m_intermediates.clear();
+         m_current_precision = boost::math::tools::digits<T>();
+      }
+      if(start + n >= bn.size())
+      {
+         std::size_t new_size = (std::min)((std::max)((std::max)(start + n, std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity()));
+         tangent_numbers_series(new_size);
+      }
+
+      for(std::size_t i = start; i < start + n; ++i)
+      {
+         if(i >= m_overflow_limit)
+            *out = policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol);
+         else
+         {
+            if(tools::max_value<T>() * tangent_scale_factor<T>() < tn[static_cast<typename container_type::size_type>(i)])
+               *out = policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol);
+            else
+               *out = tn[static_cast<typename container_type::size_type>(i)] / tangent_scale_factor<T>();
+         }
+         ++out;
+      }
+
+   #else
+      //
+      // Double-checked locking pattern, lets us access cached already cached values
+      // without locking:
+      //
+      // Get the counter and see if we need to calculate more constants:
+      //
+      if((static_cast<std::size_t>(m_counter.load(BOOST_MATH_ATOMIC_NS::memory_order_consume)) < start + n)
+         || (static_cast<int>(m_current_precision.load(BOOST_MATH_ATOMIC_NS::memory_order_consume)) < boost::math::tools::digits<T>()))
+      {
+         boost::detail::lightweight_mutex::scoped_lock l(m_mutex);
+
+         if((static_cast<std::size_t>(m_counter.load(BOOST_MATH_ATOMIC_NS::memory_order_consume)) < start + n)
+            || (static_cast<int>(m_current_precision.load(BOOST_MATH_ATOMIC_NS::memory_order_consume)) < boost::math::tools::digits<T>()))
+         {
+            if(static_cast<int>(m_current_precision.load(BOOST_MATH_ATOMIC_NS::memory_order_consume)) < boost::math::tools::digits<T>())
+            {
+               bn.clear();
+               tn.clear();
+               m_intermediates.clear();
+               m_counter.store(0, BOOST_MATH_ATOMIC_NS::memory_order_release);
+               m_current_precision = boost::math::tools::digits<T>();
+            }
+            if(start + n >= bn.size())
+            {
+               std::size_t new_size = (std::min)((std::max)((std::max)(start + n, std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity()));
+               tangent_numbers_series(new_size);
+            }
+            m_counter.store(static_cast<atomic_integer_type>(bn.size()), BOOST_MATH_ATOMIC_NS::memory_order_release);
+         }
+      }
+
+      for(std::size_t i = start; i < start + n; ++i)
+      {
+         if(i >= m_overflow_limit)
+            *out = policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol);
+         else
+         {
+            if(tools::max_value<T>() * tangent_scale_factor<T>() < tn[static_cast<typename container_type::size_type>(i)])
+               *out = policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol);
+            else
+               *out = tn[static_cast<typename container_type::size_type>(i)] / tangent_scale_factor<T>();
+         }
+         ++out;
+      }
+
+   #endif
+      return out;
+   }
+
+private:
+   //
+   // The caches for Bernoulli and tangent numbers, once allocated,
+   // these must NEVER EVER reallocate as it breaks our thread
+   // safety guarantees:
+   //
+   fixed_vector<T> bn, tn;
+   std::vector<T> m_intermediates;
+   // The value at which we know overflow has already occurred for the Bn:
+   std::size_t m_overflow_limit;
+#if !defined(BOOST_HAS_THREADS)
+   int m_current_precision;
+#elif defined(BOOST_MATH_NO_ATOMIC_INT)
+   boost::detail::lightweight_mutex m_mutex;
+   int m_current_precision;
+#else
+   boost::detail::lightweight_mutex m_mutex;
+   atomic_counter_type m_counter, m_current_precision;
+#endif
+};
+
+template <class T, class Policy>
+inline bernoulli_numbers_cache<T, Policy>& get_bernoulli_numbers_cache()
+{
+   //
+   // Force this function to be called at program startup so all the static variables
+   // get initialized then (thread safety).
+   //
+   bernoulli_initializer<T, Policy>::force_instantiate();
+   static bernoulli_numbers_cache<T, Policy> data;
+   return data;
+}
+
+}}}
+
+#endif // BOOST_MATH_BERNOULLI_DETAIL_HPP
diff --git a/ThirdParty/boost/math/special_functions/detail/erf_inv.hpp b/ThirdParty/boost/math/special_functions/detail/erf_inv.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..65011d25de58a4ce284f55bc18ab59c9a014604f
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/detail/erf_inv.hpp
@@ -0,0 +1,547 @@
+//  (C) Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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_SF_ERF_INV_HPP
+#define BOOST_MATH_SF_ERF_INV_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#pragma warning(push)
+#pragma warning(disable:4127) // Conditional expression is constant
+#pragma warning(disable:4702) // Unreachable code: optimization warning
+#endif
+
+namespace boost{ namespace math{ 
+
+namespace detail{
+//
+// The inverse erf and erfc functions share a common implementation,
+// this version is for 80-bit long double's and smaller:
+//
+template <class T, class Policy>
+T erf_inv_imp(const T& p, const T& q, const Policy&, const boost::integral_constant<int, 64>*)
+{
+   BOOST_MATH_STD_USING // for ADL of std names.
+
+   T result = 0;
+   
+   if(p <= 0.5)
+   {
+      //
+      // Evaluate inverse erf using the rational approximation:
+      //
+      // x = p(p+10)(Y+R(p))
+      //
+      // Where Y is a constant, and R(p) is optimised for a low
+      // absolute error compared to |Y|.
+      //
+      // double: Max error found: 2.001849e-18
+      // long double: Max error found: 1.017064e-20
+      // Maximum Deviation Found (actual error term at infinite precision) 8.030e-21
+      //
+      static const float Y = 0.0891314744949340820313f;
+      static const T P[] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.000508781949658280665617),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.00836874819741736770379),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.0334806625409744615033),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.0126926147662974029034),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.0365637971411762664006),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.0219878681111168899165),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.00822687874676915743155),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.00538772965071242932965)
+      };
+      static const T Q[] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.970005043303290640362),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -1.56574558234175846809),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 1.56221558398423026363),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.662328840472002992063),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.71228902341542847553),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.0527396382340099713954),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.0795283687341571680018),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.00233393759374190016776),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.000886216390456424707504)
+      };
+      T g = p * (p + 10);
+      T r = tools::evaluate_polynomial(P, p) / tools::evaluate_polynomial(Q, p);
+      result = g * Y + g * r;
+   }
+   else if(q >= 0.25)
+   {
+      //
+      // Rational approximation for 0.5 > q >= 0.25
+      //
+      // x = sqrt(-2*log(q)) / (Y + R(q))
+      //
+      // Where Y is a constant, and R(q) is optimised for a low
+      // absolute error compared to Y.
+      //
+      // double : Max error found: 7.403372e-17
+      // long double : Max error found: 6.084616e-20
+      // Maximum Deviation Found (error term) 4.811e-20
+      //
+      static const float Y = 2.249481201171875f;
+      static const T P[] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.202433508355938759655),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.105264680699391713268),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 8.37050328343119927838),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 17.6447298408374015486),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -18.8510648058714251895),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -44.6382324441786960818),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 17.445385985570866523),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 21.1294655448340526258),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -3.67192254707729348546)
+      };
+      static const T Q[] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 6.24264124854247537712),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 3.9713437953343869095),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -28.6608180499800029974),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -20.1432634680485188801),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 48.5609213108739935468),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 10.8268667355460159008),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -22.6436933413139721736),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 1.72114765761200282724)
+      };
+      T g = sqrt(-2 * log(q));
+      T xs = q - 0.25f;
+      T r = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs);
+      result = g / (Y + r);
+   }
+   else
+   {
+      //
+      // For q < 0.25 we have a series of rational approximations all
+      // of the general form:
+      //
+      // let: x = sqrt(-log(q))
+      //
+      // Then the result is given by:
+      //
+      // x(Y+R(x-B))
+      //
+      // where Y is a constant, B is the lowest value of x for which 
+      // the approximation is valid, and R(x-B) is optimised for a low
+      // absolute error compared to Y.
+      //
+      // Note that almost all code will really go through the first
+      // or maybe second approximation.  After than we're dealing with very
+      // small input values indeed: 80 and 128 bit long double's go all the
+      // way down to ~ 1e-5000 so the "tail" is rather long...
+      //
+      T x = sqrt(-log(q));
+      if(x < 3)
+      {
+         // Max error found: 1.089051e-20
+         static const float Y = 0.807220458984375f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.131102781679951906451),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.163794047193317060787),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.117030156341995252019),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.387079738972604337464),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.337785538912035898924),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.142869534408157156766),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0290157910005329060432),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.00214558995388805277169),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.679465575181126350155e-6),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.285225331782217055858e-7),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.681149956853776992068e-9)
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 3.46625407242567245975),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 5.38168345707006855425),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 4.77846592945843778382),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 2.59301921623620271374),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.848854343457902036425),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.152264338295331783612),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.01105924229346489121)
+         };
+         T xs = x - 1.125f;
+         T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs);
+         result = Y * x + R * x;
+      }
+      else if(x < 6)
+      {
+         // Max error found: 8.389174e-21
+         static const float Y = 0.93995571136474609375f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.0350353787183177984712),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.00222426529213447927281),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0185573306514231072324),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.00950804701325919603619),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.00187123492819559223345),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.000157544617424960554631),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.460469890584317994083e-5),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.230404776911882601748e-9),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.266339227425782031962e-11)
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 1.3653349817554063097),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.762059164553623404043),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.220091105764131249824),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0341589143670947727934),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.00263861676657015992959),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.764675292302794483503e-4)
+         };
+         T xs = x - 3;
+         T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs);
+         result = Y * x + R * x;
+      }
+      else if(x < 18)
+      {
+         // Max error found: 1.481312e-19
+         static const float Y = 0.98362827301025390625f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.0167431005076633737133),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.00112951438745580278863),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.00105628862152492910091),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.000209386317487588078668),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.149624783758342370182e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.449696789927706453732e-6),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.462596163522878599135e-8),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.281128735628831791805e-13),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.99055709973310326855e-16)
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.591429344886417493481),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.138151865749083321638),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0160746087093676504695),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.000964011807005165528527),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.275335474764726041141e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.282243172016108031869e-6)
+         };
+         T xs = x - 6;
+         T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs);
+         result = Y * x + R * x;
+      }
+      else if(x < 44)
+      {
+         // Max error found: 5.697761e-20
+         static const float Y = 0.99714565277099609375f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.0024978212791898131227),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.779190719229053954292e-5),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.254723037413027451751e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.162397777342510920873e-5),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.396341011304801168516e-7),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.411632831190944208473e-9),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.145596286718675035587e-11),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.116765012397184275695e-17)
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.207123112214422517181),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0169410838120975906478),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.000690538265622684595676),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.145007359818232637924e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.144437756628144157666e-6),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.509761276599778486139e-9)
+         };
+         T xs = x - 18;
+         T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs);
+         result = Y * x + R * x;
+      }
+      else
+      {
+         // Max error found: 1.279746e-20
+         static const float Y = 0.99941349029541015625f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.000539042911019078575891),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.28398759004727721098e-6),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.899465114892291446442e-6),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.229345859265920864296e-7),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.225561444863500149219e-9),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.947846627503022684216e-12),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.135880130108924861008e-14),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.348890393399948882918e-21)
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0845746234001899436914),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.00282092984726264681981),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.468292921940894236786e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.399968812193862100054e-6),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.161809290887904476097e-8),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.231558608310259605225e-11)
+         };
+         T xs = x - 44;
+         T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs);
+         result = Y * x + R * x;
+      }
+   }
+   return result;
+}
+
+template <class T, class Policy>
+struct erf_roots
+{
+   boost::math::tuple<T,T,T> operator()(const T& guess)
+   {
+      BOOST_MATH_STD_USING
+      T derivative = sign * (2 / sqrt(constants::pi<T>())) * exp(-(guess * guess));
+      T derivative2 = -2 * guess * derivative;
+      return boost::math::make_tuple(((sign > 0) ? static_cast<T>(boost::math::erf(guess, Policy()) - target) : static_cast<T>(boost::math::erfc(guess, Policy())) - target), derivative, derivative2);
+   }
+   erf_roots(T z, int s) : target(z), sign(s) {}
+private:
+   T target;
+   int sign;
+};
+
+template <class T, class Policy>
+T erf_inv_imp(const T& p, const T& q, const Policy& pol, const boost::integral_constant<int, 0>*)
+{
+   //
+   // Generic version, get a guess that's accurate to 64-bits (10^-19)
+   //
+   T guess = erf_inv_imp(p, q, pol, static_cast<boost::integral_constant<int, 64> const*>(0));
+   T result;
+   //
+   // If T has more bit's than 64 in it's mantissa then we need to iterate,
+   // otherwise we can just return the result:
+   //
+   if(policies::digits<T, Policy>() > 64)
+   {
+      boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
+      if(p <= 0.5)
+      {
+         result = tools::halley_iterate(detail::erf_roots<typename remove_cv<T>::type, Policy>(p, 1), guess, static_cast<T>(0), tools::max_value<T>(), (policies::digits<T, Policy>() * 2) / 3, max_iter);
+      }
+      else
+      {
+         result = tools::halley_iterate(detail::erf_roots<typename remove_cv<T>::type, Policy>(q, -1), guess, static_cast<T>(0), tools::max_value<T>(), (policies::digits<T, Policy>() * 2) / 3, max_iter);
+      }
+      policies::check_root_iterations<T>("boost::math::erf_inv<%1%>", max_iter, pol);
+   }
+   else
+   {
+      result = guess;
+   }
+   return result;
+}
+
+template <class T, class Policy>
+struct erf_inv_initializer
+{
+   struct init
+   {
+      init()
+      {
+         do_init();
+      }
+      static bool is_value_non_zero(T);
+      static void do_init()
+      {
+         // If std::numeric_limits<T>::digits is zero, we must not call
+         // our initialization code here as the precision presumably
+         // varies at runtime, and will not have been set yet.
+         if(std::numeric_limits<T>::digits)
+         {
+            boost::math::erf_inv(static_cast<T>(0.25), Policy());
+            boost::math::erf_inv(static_cast<T>(0.55), Policy());
+            boost::math::erf_inv(static_cast<T>(0.95), Policy());
+            boost::math::erfc_inv(static_cast<T>(1e-15), Policy());
+            // These following initializations must not be called if
+            // type T can not hold the relevant values without
+            // underflow to zero.  We check this at runtime because
+            // some tools such as valgrind silently change the precision
+            // of T at runtime, and numeric_limits basically lies!
+            if(is_value_non_zero(static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-130))))
+               boost::math::erfc_inv(static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-130)), Policy());
+
+            // Some compilers choke on constants that would underflow, even in code that isn't instantiated
+            // so try and filter these cases out in the preprocessor:
+#if LDBL_MAX_10_EXP >= 800
+            if(is_value_non_zero(static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-800))))
+               boost::math::erfc_inv(static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-800)), Policy());
+            if(is_value_non_zero(static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-900))))
+               boost::math::erfc_inv(static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-900)), Policy());
+#else
+            if(is_value_non_zero(static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 64, 1e-800))))
+               boost::math::erfc_inv(static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 64, 1e-800)), Policy());
+            if(is_value_non_zero(static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 64, 1e-900))))
+               boost::math::erfc_inv(static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 64, 1e-900)), Policy());
+#endif
+         }
+      }
+      void force_instantiate()const{}
+   };
+   static const init initializer;
+   static void force_instantiate()
+   {
+      initializer.force_instantiate();
+   }
+};
+
+template <class T, class Policy>
+const typename erf_inv_initializer<T, Policy>::init erf_inv_initializer<T, Policy>::initializer;
+
+template <class T, class Policy>
+bool erf_inv_initializer<T, Policy>::init::is_value_non_zero(T v)
+{
+   // This needs to be non-inline to detect whether v is non zero at runtime
+   // rather than at compile time, only relevant when running under valgrind
+   // which changes long double's to double's on the fly.
+   return v != 0;
+}
+
+} // namespace detail
+
+template <class T, class Policy>
+typename tools::promote_args<T>::type erfc_inv(T z, const Policy& pol)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+
+   //
+   // Begin by testing for domain errors, and other special cases:
+   //
+   static const char* function = "boost::math::erfc_inv<%1%>(%1%, %1%)";
+   if((z < 0) || (z > 2))
+      return policies::raise_domain_error<result_type>(function, "Argument outside range [0,2] in inverse erfc function (got p=%1%).", z, pol);
+   if(z == 0)
+      return policies::raise_overflow_error<result_type>(function, 0, pol);
+   if(z == 2)
+      return -policies::raise_overflow_error<result_type>(function, 0, pol);
+   //
+   // Normalise the input, so it's in the range [0,1], we will
+   // negate the result if z is outside that range.  This is a simple
+   // application of the erfc reflection formula: erfc(-z) = 2 - erfc(z)
+   //
+   result_type p, q, s;
+   if(z > 1)
+   {
+      q = 2 - z;
+      p = 1 - q;
+      s = -1;
+   }
+   else
+   {
+      p = 1 - z;
+      q = z;
+      s = 1;
+   }
+   //
+   // A bit of meta-programming to figure out which implementation
+   // to use, based on the number of bits in the mantissa of T:
+   //
+   typedef typename policies::precision<result_type, Policy>::type precision_type;
+   typedef boost::integral_constant<int,
+      precision_type::value <= 0 ? 0 :
+      precision_type::value <= 64 ? 64 : 0
+   > tag_type;
+   //
+   // Likewise use internal promotion, so we evaluate at a higher
+   // precision internally if it's appropriate:
+   //
+   typedef typename policies::evaluation<result_type, Policy>::type eval_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   detail::erf_inv_initializer<eval_type, forwarding_policy>::force_instantiate();
+
+   //
+   // And get the result, negating where required:
+   //
+   return s * policies::checked_narrowing_cast<result_type, forwarding_policy>(
+      detail::erf_inv_imp(static_cast<eval_type>(p), static_cast<eval_type>(q), forwarding_policy(), static_cast<tag_type const*>(0)), function);
+}
+
+template <class T, class Policy>
+typename tools::promote_args<T>::type erf_inv(T z, const Policy& pol)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+
+   //
+   // Begin by testing for domain errors, and other special cases:
+   //
+   static const char* function = "boost::math::erf_inv<%1%>(%1%, %1%)";
+   if((z < -1) || (z > 1))
+      return policies::raise_domain_error<result_type>(function, "Argument outside range [-1, 1] in inverse erf function (got p=%1%).", z, pol);
+   if(z == 1)
+      return policies::raise_overflow_error<result_type>(function, 0, pol);
+   if(z == -1)
+      return -policies::raise_overflow_error<result_type>(function, 0, pol);
+   if(z == 0)
+      return 0;
+   //
+   // Normalise the input, so it's in the range [0,1], we will
+   // negate the result if z is outside that range.  This is a simple
+   // application of the erf reflection formula: erf(-z) = -erf(z)
+   //
+   result_type p, q, s;
+   if(z < 0)
+   {
+      p = -z;
+      q = 1 - p;
+      s = -1;
+   }
+   else
+   {
+      p = z;
+      q = 1 - z;
+      s = 1;
+   }
+   //
+   // A bit of meta-programming to figure out which implementation
+   // to use, based on the number of bits in the mantissa of T:
+   //
+   typedef typename policies::precision<result_type, Policy>::type precision_type;
+   typedef boost::integral_constant<int,
+      precision_type::value <= 0 ? 0 :
+      precision_type::value <= 64 ? 64 : 0
+   > tag_type;
+   //
+   // Likewise use internal promotion, so we evaluate at a higher
+   // precision internally if it's appropriate:
+   //
+   typedef typename policies::evaluation<result_type, Policy>::type eval_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+   //
+   // Likewise use internal promotion, so we evaluate at a higher
+   // precision internally if it's appropriate:
+   //
+   typedef typename policies::evaluation<result_type, Policy>::type eval_type;
+
+   detail::erf_inv_initializer<eval_type, forwarding_policy>::force_instantiate();
+   //
+   // And get the result, negating where required:
+   //
+   return s * policies::checked_narrowing_cast<result_type, forwarding_policy>(
+      detail::erf_inv_imp(static_cast<eval_type>(p), static_cast<eval_type>(q), forwarding_policy(), static_cast<tag_type const*>(0)), function);
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type erfc_inv(T z)
+{
+   return erfc_inv(z, policies::policy<>());
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type erf_inv(T z)
+{
+   return erf_inv(z, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // BOOST_MATH_SF_ERF_INV_HPP
+
diff --git a/ThirdParty/boost/math/special_functions/detail/gamma_inva.hpp b/ThirdParty/boost/math/special_functions/detail/gamma_inva.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7c32d2946c0b9196ec78146fac4816b9431e1b2b
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/detail/gamma_inva.hpp
@@ -0,0 +1,233 @@
+//  (C) Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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)
+
+//
+// This is not a complete header file, it is included by gamma.hpp
+// after it has defined it's definitions.  This inverts the incomplete
+// gamma functions P and Q on the first parameter "a" using a generic
+// root finding algorithm (TOMS Algorithm 748).
+//
+
+#ifndef BOOST_MATH_SP_DETAIL_GAMMA_INVA
+#define BOOST_MATH_SP_DETAIL_GAMMA_INVA
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/tools/toms748_solve.hpp>
+#include <boost/cstdint.hpp>
+
+namespace boost{ namespace math{ namespace detail{
+
+template <class T, class Policy>
+struct gamma_inva_t
+{
+   gamma_inva_t(T z_, T p_, bool invert_) : z(z_), p(p_), invert(invert_) {}
+   T operator()(T a)
+   {
+      return invert ? p - boost::math::gamma_q(a, z, Policy()) : boost::math::gamma_p(a, z, Policy()) - p;
+   }
+private:
+   T z, p;
+   bool invert;
+};
+
+template <class T, class Policy>
+T inverse_poisson_cornish_fisher(T lambda, T p, T q, const Policy& pol)
+{
+   BOOST_MATH_STD_USING
+   // mean:
+   T m = lambda;
+   // standard deviation:
+   T sigma = sqrt(lambda);
+   // skewness
+   T sk = 1 / sigma;
+   // kurtosis:
+   // T k = 1/lambda;
+   // Get the inverse of a std normal distribution:
+   T x = boost::math::erfc_inv(p > q ? 2 * q : 2 * p, pol) * constants::root_two<T>();
+   // Set the sign:
+   if(p < 0.5)
+      x = -x;
+   T x2 = x * x;
+   // w is correction term due to skewness
+   T w = x + sk * (x2 - 1) / 6;
+   /*
+   // Add on correction due to kurtosis.
+   // Disabled for now, seems to make things worse?
+   //
+   if(lambda >= 10)
+      w += k * x * (x2 - 3) / 24 + sk * sk * x * (2 * x2 - 5) / -36;
+   */
+   w = m + sigma * w;
+   return w > tools::min_value<T>() ? w : tools::min_value<T>();
+}
+
+template <class T, class Policy>
+T gamma_inva_imp(const T& z, const T& p, const T& q, const Policy& pol)
+{
+   BOOST_MATH_STD_USING  // for ADL of std lib math functions
+   //
+   // Special cases first:
+   //
+   if(p == 0)
+   {
+      return policies::raise_overflow_error<T>("boost::math::gamma_p_inva<%1%>(%1%, %1%)", 0, Policy());
+   }
+   if(q == 0)
+   {
+      return tools::min_value<T>();
+   }
+   //
+   // Function object, this is the functor whose root
+   // we have to solve:
+   //
+   gamma_inva_t<T, Policy> f(z, (p < q) ? p : q, (p < q) ? false : true);
+   //
+   // Tolerance: full precision.
+   //
+   tools::eps_tolerance<T> tol(policies::digits<T, Policy>());
+   //
+   // Now figure out a starting guess for what a may be, 
+   // we'll start out with a value that'll put p or q
+   // right bang in the middle of their range, the functions
+   // are quite sensitive so we should need too many steps
+   // to bracket the root from there:
+   //
+   T guess;
+   T factor = 8;
+   if(z >= 1)
+   {
+      //
+      // We can use the relationship between the incomplete 
+      // gamma function and the poisson distribution to
+      // calculate an approximate inverse, for large z
+      // this is actually pretty accurate, but it fails badly
+      // when z is very small.  Also set our step-factor according
+      // to how accurate we think the result is likely to be:
+      //
+      guess = 1 + inverse_poisson_cornish_fisher(z, q, p, pol);
+      if(z > 5)
+      {
+         if(z > 1000)
+            factor = 1.01f;
+         else if(z > 50)
+            factor = 1.1f;
+         else if(guess > 10)
+            factor = 1.25f;
+         else
+            factor = 2;
+         if(guess < 1.1)
+            factor = 8;
+      }
+   }
+   else if(z > 0.5)
+   {
+      guess = z * 1.2f;
+   }
+   else
+   {
+      guess = -0.4f / log(z);
+   }
+   //
+   // Max iterations permitted:
+   //
+   boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
+   //
+   // Use our generic derivative-free root finding procedure.
+   // We could use Newton steps here, taking the PDF of the
+   // Poisson distribution as our derivative, but that's
+   // even worse performance-wise than the generic method :-(
+   //
+   std::pair<T, T> r = bracket_and_solve_root(f, guess, factor, false, tol, max_iter, pol);
+   if(max_iter >= policies::get_max_root_iterations<Policy>())
+      return policies::raise_evaluation_error<T>("boost::math::gamma_p_inva<%1%>(%1%, %1%)", "Unable to locate the root within a reasonable number of iterations, closest approximation so far was %1%", r.first, pol);
+   return (r.first + r.second) / 2;
+}
+
+} // namespace detail
+
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type 
+   gamma_p_inva(T1 x, T2 p, const Policy& pol)
+{
+   typedef typename tools::promote_args<T1, T2>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   if(p == 0)
+   {
+      policies::raise_overflow_error<result_type>("boost::math::gamma_p_inva<%1%>(%1%, %1%)", 0, Policy());
+   }
+   if(p == 1)
+   {
+      return tools::min_value<result_type>();
+   }
+
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+      detail::gamma_inva_imp(
+         static_cast<value_type>(x), 
+         static_cast<value_type>(p), 
+         static_cast<value_type>(1 - static_cast<value_type>(p)), 
+         pol), "boost::math::gamma_p_inva<%1%>(%1%, %1%)");
+}
+
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type 
+   gamma_q_inva(T1 x, T2 q, const Policy& pol)
+{
+   typedef typename tools::promote_args<T1, T2>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   if(q == 1)
+   {
+      policies::raise_overflow_error<result_type>("boost::math::gamma_q_inva<%1%>(%1%, %1%)", 0, Policy());
+   }
+   if(q == 0)
+   {
+      return tools::min_value<result_type>();
+   }
+
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+      detail::gamma_inva_imp(
+         static_cast<value_type>(x), 
+         static_cast<value_type>(1 - static_cast<value_type>(q)), 
+         static_cast<value_type>(q), 
+         pol), "boost::math::gamma_q_inva<%1%>(%1%, %1%)");
+}
+
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type 
+   gamma_p_inva(T1 x, T2 p)
+{
+   return boost::math::gamma_p_inva(x, p, policies::policy<>());
+}
+
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+   gamma_q_inva(T1 x, T2 q)
+{
+   return boost::math::gamma_q_inva(x, q, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_SP_DETAIL_GAMMA_INVA
+
+
+
diff --git a/ThirdParty/boost/math/special_functions/detail/igamma_inverse.hpp b/ThirdParty/boost/math/special_functions/detail/igamma_inverse.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..41ce93d4e30d935546f6d7f5cc18226bd34fb9b5
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/detail/igamma_inverse.hpp
@@ -0,0 +1,551 @@
+//  (C) Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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_SPECIAL_FUNCTIONS_IGAMMA_INVERSE_HPP
+#define BOOST_MATH_SPECIAL_FUNCTIONS_IGAMMA_INVERSE_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/tools/tuple.hpp>
+#include <boost/math/special_functions/gamma.hpp>
+#include <boost/math/special_functions/sign.hpp>
+#include <boost/math/tools/roots.hpp>
+#include <boost/math/policies/error_handling.hpp>
+
+namespace boost{ namespace math{
+
+namespace detail{
+
+template <class T>
+T find_inverse_s(T p, T q)
+{
+   //
+   // Computation of the Incomplete Gamma Function Ratios and their Inverse
+   // ARMIDO R. DIDONATO and ALFRED H. MORRIS, JR.
+   // ACM Transactions on Mathematical Software, Vol. 12, No. 4,
+   // December 1986, Pages 377-393.
+   //
+   // See equation 32.
+   //
+   BOOST_MATH_STD_USING
+   T t;
+   if(p < 0.5)
+   {
+      t = sqrt(-2 * log(p));
+   }
+   else
+   {
+      t = sqrt(-2 * log(q));
+   }
+   static const double a[4] = { 3.31125922108741, 11.6616720288968, 4.28342155967104, 0.213623493715853 };
+   static const double b[5] = { 1, 6.61053765625462, 6.40691597760039, 1.27364489782223, 0.3611708101884203e-1 };
+   T s = t - tools::evaluate_polynomial(a, t) / tools::evaluate_polynomial(b, t);
+   if(p < 0.5)
+      s = -s;
+   return s;
+}
+
+template <class T>
+T didonato_SN(T a, T x, unsigned N, T tolerance = 0)
+{
+   //
+   // Computation of the Incomplete Gamma Function Ratios and their Inverse
+   // ARMIDO R. DIDONATO and ALFRED H. MORRIS, JR.
+   // ACM Transactions on Mathematical Software, Vol. 12, No. 4,
+   // December 1986, Pages 377-393.
+   //
+   // See equation 34.
+   //
+   T sum = 1;
+   if(N >= 1)
+   {
+      T partial = x / (a + 1);
+      sum += partial;
+      for(unsigned i = 2; i <= N; ++i)
+      {
+         partial *= x / (a + i);
+         sum += partial;
+         if(partial < tolerance)
+            break;
+      }
+   }
+   return sum;
+}
+
+template <class T, class Policy>
+inline T didonato_FN(T p, T a, T x, unsigned N, T tolerance, const Policy& pol)
+{
+   //
+   // Computation of the Incomplete Gamma Function Ratios and their Inverse
+   // ARMIDO R. DIDONATO and ALFRED H. MORRIS, JR.
+   // ACM Transactions on Mathematical Software, Vol. 12, No. 4,
+   // December 1986, Pages 377-393.
+   //
+   // See equation 34.
+   //
+   BOOST_MATH_STD_USING
+   T u = log(p) + boost::math::lgamma(a + 1, pol);
+   return exp((u + x - log(didonato_SN(a, x, N, tolerance))) / a);
+}
+
+template <class T, class Policy>
+T find_inverse_gamma(T a, T p, T q, const Policy& pol, bool* p_has_10_digits)
+{
+   //
+   // In order to understand what's going on here, you will
+   // need to refer to:
+   //
+   // Computation of the Incomplete Gamma Function Ratios and their Inverse
+   // ARMIDO R. DIDONATO and ALFRED H. MORRIS, JR.
+   // ACM Transactions on Mathematical Software, Vol. 12, No. 4,
+   // December 1986, Pages 377-393.
+   //
+   BOOST_MATH_STD_USING
+
+   T result;
+   *p_has_10_digits = false;
+
+   if(a == 1)
+   {
+      result = -log(q);
+      BOOST_MATH_INSTRUMENT_VARIABLE(result);
+   }
+   else if(a < 1)
+   {
+      T g = boost::math::tgamma(a, pol);
+      T b = q * g;
+      BOOST_MATH_INSTRUMENT_VARIABLE(g);
+      BOOST_MATH_INSTRUMENT_VARIABLE(b);
+      if((b > 0.6) || ((b >= 0.45) && (a >= 0.3)))
+      {
+         // DiDonato & Morris Eq 21: 
+         //
+         // There is a slight variation from DiDonato and Morris here:
+         // the first form given here is unstable when p is close to 1,
+         // making it impossible to compute the inverse of Q(a,x) for small
+         // q.  Fortunately the second form works perfectly well in this case.
+         //
+         T u;
+         if((b * q > 1e-8) && (q > 1e-5))
+         {
+            u = pow(p * g * a, 1 / a);
+            BOOST_MATH_INSTRUMENT_VARIABLE(u);
+         }
+         else
+         {
+            u = exp((-q / a) - constants::euler<T>());
+            BOOST_MATH_INSTRUMENT_VARIABLE(u);
+         }
+         result = u / (1 - (u / (a + 1)));
+         BOOST_MATH_INSTRUMENT_VARIABLE(result);
+      }
+      else if((a < 0.3) && (b >= 0.35))
+      {
+         // DiDonato & Morris Eq 22:
+         T t = exp(-constants::euler<T>() - b);
+         T u = t * exp(t);
+         result = t * exp(u);
+         BOOST_MATH_INSTRUMENT_VARIABLE(result);
+      }
+      else if((b > 0.15) || (a >= 0.3))
+      {
+         // DiDonato & Morris Eq 23:
+         T y = -log(b);
+         T u = y - (1 - a) * log(y);
+         result = y - (1 - a) * log(u) - log(1 + (1 - a) / (1 + u));
+         BOOST_MATH_INSTRUMENT_VARIABLE(result);
+      }
+      else if (b > 0.1)
+      {
+         // DiDonato & Morris Eq 24:
+         T y = -log(b);
+         T u = y - (1 - a) * log(y);
+         result = y - (1 - a) * log(u) - log((u * u + 2 * (3 - a) * u + (2 - a) * (3 - a)) / (u * u + (5 - a) * u + 2));
+         BOOST_MATH_INSTRUMENT_VARIABLE(result);
+      }
+      else
+      {
+         // DiDonato & Morris Eq 25:
+         T y = -log(b);
+         T c1 = (a - 1) * log(y);
+         T c1_2 = c1 * c1;
+         T c1_3 = c1_2 * c1;
+         T c1_4 = c1_2 * c1_2;
+         T a_2 = a * a;
+         T a_3 = a_2 * a;
+
+         T c2 = (a - 1) * (1 + c1);
+         T c3 = (a - 1) * (-(c1_2 / 2) + (a - 2) * c1 + (3 * a - 5) / 2);
+         T c4 = (a - 1) * ((c1_3 / 3) - (3 * a - 5) * c1_2 / 2 + (a_2 - 6 * a + 7) * c1 + (11 * a_2 - 46 * a + 47) / 6);
+         T c5 = (a - 1) * (-(c1_4 / 4)
+                           + (11 * a - 17) * c1_3 / 6
+                           + (-3 * a_2 + 13 * a -13) * c1_2
+                           + (2 * a_3 - 25 * a_2 + 72 * a - 61) * c1 / 2
+                           + (25 * a_3 - 195 * a_2 + 477 * a - 379) / 12);
+
+         T y_2 = y * y;
+         T y_3 = y_2 * y;
+         T y_4 = y_2 * y_2;
+         result = y + c1 + (c2 / y) + (c3 / y_2) + (c4 / y_3) + (c5 / y_4);
+         BOOST_MATH_INSTRUMENT_VARIABLE(result);
+         if(b < 1e-28f)
+            *p_has_10_digits = true;
+      }
+   }
+   else
+   {
+      // DiDonato and Morris Eq 31:
+      T s = find_inverse_s(p, q);
+
+      BOOST_MATH_INSTRUMENT_VARIABLE(s);
+
+      T s_2 = s * s;
+      T s_3 = s_2 * s;
+      T s_4 = s_2 * s_2;
+      T s_5 = s_4 * s;
+      T ra = sqrt(a);
+
+      BOOST_MATH_INSTRUMENT_VARIABLE(ra);
+
+      T w = a + s * ra + (s * s -1) / 3;
+      w += (s_3 - 7 * s) / (36 * ra);
+      w -= (3 * s_4 + 7 * s_2 - 16) / (810 * a);
+      w += (9 * s_5 + 256 * s_3 - 433 * s) / (38880 * a * ra);
+
+      BOOST_MATH_INSTRUMENT_VARIABLE(w);
+
+      if((a >= 500) && (fabs(1 - w / a) < 1e-6))
+      {
+         result = w;
+         *p_has_10_digits = true;
+         BOOST_MATH_INSTRUMENT_VARIABLE(result);
+      }
+      else if (p > 0.5)
+      {
+         if(w < 3 * a)
+         {
+            result = w;
+            BOOST_MATH_INSTRUMENT_VARIABLE(result);
+         }
+         else
+         {
+            T D = (std::max)(T(2), T(a * (a - 1)));
+            T lg = boost::math::lgamma(a, pol);
+            T lb = log(q) + lg;
+            if(lb < -D * 2.3)
+            {
+               // DiDonato and Morris Eq 25:
+               T y = -lb;
+               T c1 = (a - 1) * log(y);
+               T c1_2 = c1 * c1;
+               T c1_3 = c1_2 * c1;
+               T c1_4 = c1_2 * c1_2;
+               T a_2 = a * a;
+               T a_3 = a_2 * a;
+
+               T c2 = (a - 1) * (1 + c1);
+               T c3 = (a - 1) * (-(c1_2 / 2) + (a - 2) * c1 + (3 * a - 5) / 2);
+               T c4 = (a - 1) * ((c1_3 / 3) - (3 * a - 5) * c1_2 / 2 + (a_2 - 6 * a + 7) * c1 + (11 * a_2 - 46 * a + 47) / 6);
+               T c5 = (a - 1) * (-(c1_4 / 4)
+                                 + (11 * a - 17) * c1_3 / 6
+                                 + (-3 * a_2 + 13 * a -13) * c1_2
+                                 + (2 * a_3 - 25 * a_2 + 72 * a - 61) * c1 / 2
+                                 + (25 * a_3 - 195 * a_2 + 477 * a - 379) / 12);
+
+               T y_2 = y * y;
+               T y_3 = y_2 * y;
+               T y_4 = y_2 * y_2;
+               result = y + c1 + (c2 / y) + (c3 / y_2) + (c4 / y_3) + (c5 / y_4);
+               BOOST_MATH_INSTRUMENT_VARIABLE(result);
+            }
+            else
+            {
+               // DiDonato and Morris Eq 33:
+               T u = -lb + (a - 1) * log(w) - log(1 + (1 - a) / (1 + w));
+               result = -lb + (a - 1) * log(u) - log(1 + (1 - a) / (1 + u));
+               BOOST_MATH_INSTRUMENT_VARIABLE(result);
+            }
+         }
+      }
+      else
+      {
+         T z = w;
+         T ap1 = a + 1;
+         T ap2 = a + 2;
+         if(w < 0.15f * ap1)
+         {
+            // DiDonato and Morris Eq 35:
+            T v = log(p) + boost::math::lgamma(ap1, pol);
+            z = exp((v + w) / a);
+            s = boost::math::log1p(z / ap1 * (1 + z / ap2), pol);
+            z = exp((v + z - s) / a);
+            s = boost::math::log1p(z / ap1 * (1 + z / ap2), pol);
+            z = exp((v + z - s) / a);
+            s = boost::math::log1p(z / ap1 * (1 + z / ap2 * (1 + z / (a + 3))), pol);
+            z = exp((v + z - s) / a);
+            BOOST_MATH_INSTRUMENT_VARIABLE(z);
+         }
+
+         if((z <= 0.01 * ap1) || (z > 0.7 * ap1))
+         {
+            result = z;
+            if(z <= 0.002 * ap1)
+               *p_has_10_digits = true;
+            BOOST_MATH_INSTRUMENT_VARIABLE(result);
+         }
+         else
+         {
+            // DiDonato and Morris Eq 36:
+            T ls = log(didonato_SN(a, z, 100, T(1e-4)));
+            T v = log(p) + boost::math::lgamma(ap1, pol);
+            z = exp((v + z - ls) / a);
+            result = z * (1 - (a * log(z) - z - v + ls) / (a - z));
+
+            BOOST_MATH_INSTRUMENT_VARIABLE(result);
+         }
+      }
+   }
+   return result;
+}
+
+template <class T, class Policy>
+struct gamma_p_inverse_func
+{
+   gamma_p_inverse_func(T a_, T p_, bool inv) : a(a_), p(p_), invert(inv)
+   {
+      //
+      // If p is too near 1 then P(x) - p suffers from cancellation
+      // errors causing our root-finding algorithms to "thrash", better
+      // to invert in this case and calculate Q(x) - (1-p) instead.
+      //
+      // Of course if p is *very* close to 1, then the answer we get will
+      // be inaccurate anyway (because there's not enough information in p)
+      // but at least we will converge on the (inaccurate) answer quickly.
+      //
+      if(p > 0.9)
+      {
+         p = 1 - p;
+         invert = !invert;
+      }
+   }
+
+   boost::math::tuple<T, T, T> operator()(const T& x)const
+   {
+      BOOST_FPU_EXCEPTION_GUARD
+      //
+      // Calculate P(x) - p and the first two derivates, or if the invert
+      // flag is set, then Q(x) - q and it's derivatives.
+      //
+      typedef typename policies::evaluation<T, Policy>::type value_type;
+      // typedef typename lanczos::lanczos<T, Policy>::type evaluation_type;
+      typedef typename policies::normalise<
+         Policy, 
+         policies::promote_float<false>, 
+         policies::promote_double<false>, 
+         policies::discrete_quantile<>,
+         policies::assert_undefined<> >::type forwarding_policy;
+
+      BOOST_MATH_STD_USING  // For ADL of std functions.
+
+      T f, f1;
+      value_type ft;
+      f = static_cast<T>(boost::math::detail::gamma_incomplete_imp(
+               static_cast<value_type>(a), 
+               static_cast<value_type>(x), 
+               true, invert,
+               forwarding_policy(), &ft));
+      f1 = static_cast<T>(ft);
+      T f2;
+      T div = (a - x - 1) / x;
+      f2 = f1;
+      if((fabs(div) > 1) && (tools::max_value<T>() / fabs(div) < f2))
+      {
+         // overflow:
+         f2 = -tools::max_value<T>() / 2;
+      }
+      else
+      {
+         f2 *= div;
+      }
+
+      if(invert)
+      {
+         f1 = -f1;
+         f2 = -f2;
+      }
+
+      return boost::math::make_tuple(static_cast<T>(f - p), f1, f2);
+   }
+private:
+   T a, p;
+   bool invert;
+};
+
+template <class T, class Policy>
+T gamma_p_inv_imp(T a, T p, const Policy& pol)
+{
+   BOOST_MATH_STD_USING  // ADL of std functions.
+
+   static const char* function = "boost::math::gamma_p_inv<%1%>(%1%, %1%)";
+
+   BOOST_MATH_INSTRUMENT_VARIABLE(a);
+   BOOST_MATH_INSTRUMENT_VARIABLE(p);
+
+   if(a <= 0)
+      return policies::raise_domain_error<T>(function, "Argument a in the incomplete gamma function inverse must be >= 0 (got a=%1%).", a, pol);
+   if((p < 0) || (p > 1))
+      return policies::raise_domain_error<T>(function, "Probability must be in the range [0,1] in the incomplete gamma function inverse (got p=%1%).", p, pol);
+   if(p == 1)
+      return policies::raise_overflow_error<T>(function, 0, Policy());
+   if(p == 0)
+      return 0;
+   bool has_10_digits;
+   T guess = detail::find_inverse_gamma<T>(a, p, 1 - p, pol, &has_10_digits);
+   if((policies::digits<T, Policy>() <= 36) && has_10_digits)
+      return guess;
+   T lower = tools::min_value<T>();
+   if(guess <= lower)
+      guess = tools::min_value<T>();
+   BOOST_MATH_INSTRUMENT_VARIABLE(guess);
+   //
+   // Work out how many digits to converge to, normally this is
+   // 2/3 of the digits in T, but if the first derivative is very
+   // large convergence is slow, so we'll bump it up to full 
+   // precision to prevent premature termination of the root-finding routine.
+   //
+   unsigned digits = policies::digits<T, Policy>();
+   if(digits < 30)
+   {
+      digits *= 2;
+      digits /= 3;
+   }
+   else
+   {
+      digits /= 2;
+      digits -= 1;
+   }
+   if((a < 0.125) && (fabs(gamma_p_derivative(a, guess, pol)) > 1 / sqrt(tools::epsilon<T>())))
+      digits = policies::digits<T, Policy>() - 2;
+   //
+   // Go ahead and iterate:
+   //
+   boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
+   guess = tools::halley_iterate(
+      detail::gamma_p_inverse_func<T, Policy>(a, p, false),
+      guess,
+      lower,
+      tools::max_value<T>(),
+      digits,
+      max_iter);
+   policies::check_root_iterations<T>(function, max_iter, pol);
+   BOOST_MATH_INSTRUMENT_VARIABLE(guess);
+   if(guess == lower)
+      guess = policies::raise_underflow_error<T>(function, "Expected result known to be non-zero, but is smaller than the smallest available number.", pol);
+   return guess;
+}
+
+template <class T, class Policy>
+T gamma_q_inv_imp(T a, T q, const Policy& pol)
+{
+   BOOST_MATH_STD_USING  // ADL of std functions.
+
+   static const char* function = "boost::math::gamma_q_inv<%1%>(%1%, %1%)";
+
+   if(a <= 0)
+      return policies::raise_domain_error<T>(function, "Argument a in the incomplete gamma function inverse must be >= 0 (got a=%1%).", a, pol);
+   if((q < 0) || (q > 1))
+      return policies::raise_domain_error<T>(function, "Probability must be in the range [0,1] in the incomplete gamma function inverse (got q=%1%).", q, pol);
+   if(q == 0)
+      return policies::raise_overflow_error<T>(function, 0, Policy());
+   if(q == 1)
+      return 0;
+   bool has_10_digits;
+   T guess = detail::find_inverse_gamma<T>(a, 1 - q, q, pol, &has_10_digits);
+   if((policies::digits<T, Policy>() <= 36) && has_10_digits)
+      return guess;
+   T lower = tools::min_value<T>();
+   if(guess <= lower)
+      guess = tools::min_value<T>();
+   //
+   // Work out how many digits to converge to, normally this is
+   // 2/3 of the digits in T, but if the first derivative is very
+   // large convergence is slow, so we'll bump it up to full 
+   // precision to prevent premature termination of the root-finding routine.
+   //
+   unsigned digits = policies::digits<T, Policy>();
+   if(digits < 30)
+   {
+      digits *= 2;
+      digits /= 3;
+   }
+   else
+   {
+      digits /= 2;
+      digits -= 1;
+   }
+   if((a < 0.125) && (fabs(gamma_p_derivative(a, guess, pol)) > 1 / sqrt(tools::epsilon<T>())))
+      digits = policies::digits<T, Policy>();
+   //
+   // Go ahead and iterate:
+   //
+   boost::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
+   guess = tools::halley_iterate(
+      detail::gamma_p_inverse_func<T, Policy>(a, q, true),
+      guess,
+      lower,
+      tools::max_value<T>(),
+      digits,
+      max_iter);
+   policies::check_root_iterations<T>(function, max_iter, pol);
+   if(guess == lower)
+      guess = policies::raise_underflow_error<T>(function, "Expected result known to be non-zero, but is smaller than the smallest available number.", pol);
+   return guess;
+}
+
+} // namespace detail
+
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type 
+   gamma_p_inv(T1 a, T2 p, const Policy& pol)
+{
+   typedef typename tools::promote_args<T1, T2>::type result_type;
+   return detail::gamma_p_inv_imp(
+      static_cast<result_type>(a),
+      static_cast<result_type>(p), pol);
+}
+
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type 
+   gamma_q_inv(T1 a, T2 p, const Policy& pol)
+{
+   typedef typename tools::promote_args<T1, T2>::type result_type;
+   return detail::gamma_q_inv_imp(
+      static_cast<result_type>(a),
+      static_cast<result_type>(p), pol);
+}
+
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type 
+   gamma_p_inv(T1 a, T2 p)
+{
+   return gamma_p_inv(a, p, policies::policy<>());
+}
+
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type 
+   gamma_q_inv(T1 a, T2 p)
+{
+   return gamma_q_inv(a, p, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_SPECIAL_FUNCTIONS_IGAMMA_INVERSE_HPP
+
+
+
diff --git a/ThirdParty/boost/math/special_functions/detail/igamma_large.hpp b/ThirdParty/boost/math/special_functions/detail/igamma_large.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c2c3ff0532aef780bfe6318ab9247709dde8db43
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/detail/igamma_large.hpp
@@ -0,0 +1,778 @@
+//  Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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)
+//
+// This file implements the asymptotic expansions of the incomplete
+// gamma functions P(a, x) and Q(a, x), used when a is large and
+// x ~ a.
+//
+// The primary reference is:
+//
+// "The Asymptotic Expansion of the Incomplete Gamma Functions"
+// N. M. Temme.
+// Siam J. Math Anal. Vol 10 No 4, July 1979, p757.
+//
+// A different way of evaluating these expansions,
+// plus a lot of very useful background information is in:
+// 
+// "A Set of Algorithms For the Incomplete Gamma Functions."
+// N. M. Temme.
+// Probability in the Engineering and Informational Sciences,
+// 8, 1994, 291.
+//
+// An alternative implementation is in:
+//
+// "Computation of the Incomplete Gamma Function Ratios and their Inverse."
+// A. R. Didonato and A. H. Morris.
+// ACM TOMS, Vol 12, No 4, Dec 1986, p377.
+//
+// There are various versions of the same code below, each accurate
+// to a different precision.  To understand the code, refer to Didonato
+// and Morris, from Eq 17 and 18 onwards.
+//
+// The coefficients used here are not taken from Didonato and Morris:
+// the domain over which these expansions are used is slightly different
+// to theirs, and their constants are not quite accurate enough for
+// 128-bit long double's.  Instead the coefficients were calculated
+// using the methods described by Temme p762 from Eq 3.8 onwards.
+// The values obtained agree with those obtained by Didonato and Morris
+// (at least to the first 30 digits that they provide).
+// At double precision the degrees of polynomial required for full
+// machine precision are close to those recommended to Didonato and Morris,
+// but of course many more terms are needed for larger types.
+//
+#ifndef BOOST_MATH_DETAIL_IGAMMA_LARGE
+#define BOOST_MATH_DETAIL_IGAMMA_LARGE
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128)
+//
+// This is the only way we can avoid
+// warning: non-standard suffix on floating constant [-Wpedantic]
+// when building with -Wall -pedantic.  Neither __extension__
+// nor #pragma diagnostic ignored work :(
+//
+#pragma GCC system_header
+#endif
+
+namespace boost{ namespace math{ namespace detail{
+
+// This version will never be called (at runtime), it's a stub used
+// when T is unsuitable to be passed to these routines:
+//
+template <class T, class Policy>
+inline T igamma_temme_large(T, T, const Policy& /* pol */, boost::integral_constant<int, 0> const *)
+{
+   // stub function, should never actually be called
+   BOOST_ASSERT(0);
+   return 0;
+}
+//
+// This version is accurate for up to 64-bit mantissa's, 
+// (80-bit long double, or 10^-20).
+//
+template <class T, class Policy>
+T igamma_temme_large(T a, T x, const Policy& pol, boost::integral_constant<int, 64> const *)
+{
+   BOOST_MATH_STD_USING // ADL of std functions
+   T sigma = (x - a) / a;
+   T phi = -boost::math::log1pmx(sigma, pol);
+   T y = a * phi;
+   T z = sqrt(2 * phi);
+   if(x < a)
+      z = -z;
+
+   T workspace[13];
+
+   static const T C0[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.333333333333333333333),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.0833333333333333333333),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.0148148148148148148148),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.00115740740740740740741),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.000352733686067019400353),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.0001787551440329218107),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.39192631785224377817e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.218544851067999216147e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.18540622107151599607e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.829671134095308600502e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.176659527368260793044e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.670785354340149858037e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.102618097842403080426e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.438203601845335318655e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.914769958223679023418e-9),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.255141939949462497669e-10),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.583077213255042506746e-10),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.243619480206674162437e-10),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.502766928011417558909e-11),
+   };
+   workspace[0] = tools::evaluate_polynomial(C0, z);
+
+   static const T C1[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.00185185185185185185185),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.00347222222222222222222),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.00264550264550264550265),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.000990226337448559670782),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.000205761316872427983539),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.40187757201646090535e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.18098550334489977837e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.764916091608111008464e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.161209008945634460038e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.464712780280743434226e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.137863344691572095931e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.575254560351770496402e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.119516285997781473243e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.175432417197476476238e-10),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.100915437106004126275e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.416279299184258263623e-9),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.856390702649298063807e-10),
+   };
+   workspace[1] = tools::evaluate_polynomial(C1, z);
+
+   static const T C2[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.00413359788359788359788),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.00268132716049382716049),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.000771604938271604938272),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.200938786008230452675e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.000107366532263651605215),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.529234488291201254164e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.127606351886187277134e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.342357873409613807419e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.137219573090629332056e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.629899213838005502291e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.142806142060642417916e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.204770984219908660149e-9),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.140925299108675210533e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.622897408492202203356e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.136704883966171134993e-8),
+   };
+   workspace[2] = tools::evaluate_polynomial(C2, z);
+
+   static const T C3[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.000649434156378600823045),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.000229472093621399176955),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.000469189494395255712128),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.000267720632062838852962),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.756180167188397641073e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.239650511386729665193e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.110826541153473023615e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.56749528269915965675e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.142309007324358839146e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.278610802915281422406e-10),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.169584040919302772899e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.809946490538808236335e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.191111684859736540607e-7),
+   };
+   workspace[3] = tools::evaluate_polynomial(C3, z);
+
+   static const T C4[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.000861888290916711698605),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.000784039221720066627474),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.000299072480303190179733),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.146384525788434181781e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.664149821546512218666e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.396836504717943466443e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.113757269706784190981e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.250749722623753280165e-9),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.169541495365583060147e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.890750753220530968883e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.229293483400080487057e-6),
+   };
+   workspace[4] = tools::evaluate_polynomial(C4, z);
+
+   static const T C5[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.000336798553366358150309),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.697281375836585777429e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.000277275324495939207873),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.000199325705161888477003),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.679778047793720783882e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.141906292064396701483e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.135940481897686932785e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.801847025633420153972e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.229148117650809517038e-5),
+   };
+   workspace[5] = tools::evaluate_polynomial(C5, z);
+
+   static const T C6[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.000531307936463992223166),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.000592166437353693882865),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.000270878209671804482771),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.790235323266032787212e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.815396936756196875093e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.561168275310624965004e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.183291165828433755673e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.307961345060330478256e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.346515536880360908674e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.20291327396058603727e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.57887928631490037089e-6),
+   };
+   workspace[6] = tools::evaluate_polynomial(C6, z);
+
+   static const T C7[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.000344367606892377671254),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.517179090826059219337e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.000334931610811422363117),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.000281269515476323702274),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.000109765822446847310235),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.127410090954844853795e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.277444515115636441571e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.182634888057113326614e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.578769494973505239894e-5),
+   };
+   workspace[7] = tools::evaluate_polynomial(C7, z);
+
+   static const T C8[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.000652623918595309418922),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.000839498720672087279993),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.000438297098541721005061),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.696909145842055197137e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.000166448466420675478374),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.000127835176797692185853),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.462995326369130429061e-4),
+   };
+   workspace[8] = tools::evaluate_polynomial(C8, z);
+
+   static const T C9[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.000596761290192746250124),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.720489541602001055909e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.000678230883766732836162),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.0006401475260262758451),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.000277501076343287044992),
+   };
+   workspace[9] = tools::evaluate_polynomial(C9, z);
+
+   static const T C10[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.00133244544948006563713),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.0019144384985654775265),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.00110893691345966373396),
+   };
+   workspace[10] = tools::evaluate_polynomial(C10, z);
+
+   static const T C11[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.00157972766073083495909),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.000162516262783915816899),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.00206334210355432762645),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.00213896861856890981541),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.00101085593912630031708),
+   };
+   workspace[11] = tools::evaluate_polynomial(C11, z);
+
+   static const T C12[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.00407251211951401664727),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.00640336283380806979482),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.00404101610816766177474),
+   };
+   workspace[12] = tools::evaluate_polynomial(C12, z);
+
+   T result = tools::evaluate_polynomial<13, T, T>(workspace, 1/a);
+   result *= exp(-y) / sqrt(2 * constants::pi<T>() * a);
+   if(x < a)
+      result = -result;
+
+   result += boost::math::erfc(sqrt(y), pol) / 2;
+
+   return result;
+}
+//
+// This one is accurate for 53-bit mantissa's
+// (IEEE double precision or 10^-17).
+//
+template <class T, class Policy>
+T igamma_temme_large(T a, T x, const Policy& pol, boost::integral_constant<int, 53> const *)
+{
+   BOOST_MATH_STD_USING // ADL of std functions
+   T sigma = (x - a) / a;
+   T phi = -boost::math::log1pmx(sigma, pol);
+   T y = a * phi;
+   T z = sqrt(2 * phi);
+   if(x < a)
+      z = -z;
+
+   T workspace[10];
+
+   static const T C0[] = {
+      static_cast<T>(-0.33333333333333333L),
+      static_cast<T>(0.083333333333333333L),
+      static_cast<T>(-0.014814814814814815L),
+      static_cast<T>(0.0011574074074074074L),
+      static_cast<T>(0.0003527336860670194L),
+      static_cast<T>(-0.00017875514403292181L),
+      static_cast<T>(0.39192631785224378e-4L),
+      static_cast<T>(-0.21854485106799922e-5L),
+      static_cast<T>(-0.185406221071516e-5L),
+      static_cast<T>(0.8296711340953086e-6L),
+      static_cast<T>(-0.17665952736826079e-6L),
+      static_cast<T>(0.67078535434014986e-8L),
+      static_cast<T>(0.10261809784240308e-7L),
+      static_cast<T>(-0.43820360184533532e-8L),
+      static_cast<T>(0.91476995822367902e-9L),
+   };
+   workspace[0] = tools::evaluate_polynomial(C0, z);
+
+   static const T C1[] = {
+      static_cast<T>(-0.0018518518518518519L),
+      static_cast<T>(-0.0034722222222222222L),
+      static_cast<T>(0.0026455026455026455L),
+      static_cast<T>(-0.00099022633744855967L),
+      static_cast<T>(0.00020576131687242798L),
+      static_cast<T>(-0.40187757201646091e-6L),
+      static_cast<T>(-0.18098550334489978e-4L),
+      static_cast<T>(0.76491609160811101e-5L),
+      static_cast<T>(-0.16120900894563446e-5L),
+      static_cast<T>(0.46471278028074343e-8L),
+      static_cast<T>(0.1378633446915721e-6L),
+      static_cast<T>(-0.5752545603517705e-7L),
+      static_cast<T>(0.11951628599778147e-7L),
+   };
+   workspace[1] = tools::evaluate_polynomial(C1, z);
+
+   static const T C2[] = {
+      static_cast<T>(0.0041335978835978836L),
+      static_cast<T>(-0.0026813271604938272L),
+      static_cast<T>(0.00077160493827160494L),
+      static_cast<T>(0.20093878600823045e-5L),
+      static_cast<T>(-0.00010736653226365161L),
+      static_cast<T>(0.52923448829120125e-4L),
+      static_cast<T>(-0.12760635188618728e-4L),
+      static_cast<T>(0.34235787340961381e-7L),
+      static_cast<T>(0.13721957309062933e-5L),
+      static_cast<T>(-0.6298992138380055e-6L),
+      static_cast<T>(0.14280614206064242e-6L),
+   };
+   workspace[2] = tools::evaluate_polynomial(C2, z);
+
+   static const T C3[] = {
+      static_cast<T>(0.00064943415637860082L),
+      static_cast<T>(0.00022947209362139918L),
+      static_cast<T>(-0.00046918949439525571L),
+      static_cast<T>(0.00026772063206283885L),
+      static_cast<T>(-0.75618016718839764e-4L),
+      static_cast<T>(-0.23965051138672967e-6L),
+      static_cast<T>(0.11082654115347302e-4L),
+      static_cast<T>(-0.56749528269915966e-5L),
+      static_cast<T>(0.14230900732435884e-5L),
+   };
+   workspace[3] = tools::evaluate_polynomial(C3, z);
+
+   static const T C4[] = {
+      static_cast<T>(-0.0008618882909167117L),
+      static_cast<T>(0.00078403922172006663L),
+      static_cast<T>(-0.00029907248030319018L),
+      static_cast<T>(-0.14638452578843418e-5L),
+      static_cast<T>(0.66414982154651222e-4L),
+      static_cast<T>(-0.39683650471794347e-4L),
+      static_cast<T>(0.11375726970678419e-4L),
+   };
+   workspace[4] = tools::evaluate_polynomial(C4, z);
+
+   static const T C5[] = {
+      static_cast<T>(-0.00033679855336635815L),
+      static_cast<T>(-0.69728137583658578e-4L),
+      static_cast<T>(0.00027727532449593921L),
+      static_cast<T>(-0.00019932570516188848L),
+      static_cast<T>(0.67977804779372078e-4L),
+      static_cast<T>(0.1419062920643967e-6L),
+      static_cast<T>(-0.13594048189768693e-4L),
+      static_cast<T>(0.80184702563342015e-5L),
+      static_cast<T>(-0.22914811765080952e-5L),
+   };
+   workspace[5] = tools::evaluate_polynomial(C5, z);
+
+   static const T C6[] = {
+      static_cast<T>(0.00053130793646399222L),
+      static_cast<T>(-0.00059216643735369388L),
+      static_cast<T>(0.00027087820967180448L),
+      static_cast<T>(0.79023532326603279e-6L),
+      static_cast<T>(-0.81539693675619688e-4L),
+      static_cast<T>(0.56116827531062497e-4L),
+      static_cast<T>(-0.18329116582843376e-4L),
+   };
+   workspace[6] = tools::evaluate_polynomial(C6, z);
+
+   static const T C7[] = {
+      static_cast<T>(0.00034436760689237767L),
+      static_cast<T>(0.51717909082605922e-4L),
+      static_cast<T>(-0.00033493161081142236L),
+      static_cast<T>(0.0002812695154763237L),
+      static_cast<T>(-0.00010976582244684731L),
+   };
+   workspace[7] = tools::evaluate_polynomial(C7, z);
+
+   static const T C8[] = {
+      static_cast<T>(-0.00065262391859530942L),
+      static_cast<T>(0.00083949872067208728L),
+      static_cast<T>(-0.00043829709854172101L),
+   };
+   workspace[8] = tools::evaluate_polynomial(C8, z);
+   workspace[9] = static_cast<T>(-0.00059676129019274625L);
+
+   T result = tools::evaluate_polynomial<10, T, T>(workspace, 1/a);
+   result *= exp(-y) / sqrt(2 * constants::pi<T>() * a);
+   if(x < a)
+      result = -result;
+
+   result += boost::math::erfc(sqrt(y), pol) / 2;
+
+   return result;
+}
+//
+// This one is accurate for 24-bit mantissa's
+// (IEEE float precision, or 10^-8)
+//
+template <class T, class Policy>
+T igamma_temme_large(T a, T x, const Policy& pol, boost::integral_constant<int, 24> const *)
+{
+   BOOST_MATH_STD_USING // ADL of std functions
+   T sigma = (x - a) / a;
+   T phi = -boost::math::log1pmx(sigma, pol);
+   T y = a * phi;
+   T z = sqrt(2 * phi);
+   if(x < a)
+      z = -z;
+
+   T workspace[3];
+
+   static const T C0[] = {
+      static_cast<T>(-0.333333333L),
+      static_cast<T>(0.0833333333L),
+      static_cast<T>(-0.0148148148L),
+      static_cast<T>(0.00115740741L),
+      static_cast<T>(0.000352733686L),
+      static_cast<T>(-0.000178755144L),
+      static_cast<T>(0.391926318e-4L),
+   };
+   workspace[0] = tools::evaluate_polynomial(C0, z);
+
+   static const T C1[] = {
+      static_cast<T>(-0.00185185185L),
+      static_cast<T>(-0.00347222222L),
+      static_cast<T>(0.00264550265L),
+      static_cast<T>(-0.000990226337L),
+      static_cast<T>(0.000205761317L),
+   };
+   workspace[1] = tools::evaluate_polynomial(C1, z);
+
+   static const T C2[] = {
+      static_cast<T>(0.00413359788L),
+      static_cast<T>(-0.00268132716L),
+      static_cast<T>(0.000771604938L),
+   };
+   workspace[2] = tools::evaluate_polynomial(C2, z);
+
+   T result = tools::evaluate_polynomial(workspace, 1/a);
+   result *= exp(-y) / sqrt(2 * constants::pi<T>() * a);
+   if(x < a)
+      result = -result;
+
+   result += boost::math::erfc(sqrt(y), pol) / 2;
+
+   return result;
+}
+//
+// And finally, a version for 113-bit mantissa's
+// (128-bit long doubles, or 10^-34).
+// Note this one has been optimised for a > 200
+// It's use for a < 200 is not recommended, that would
+// require many more terms in the polynomials.
+//
+template <class T, class Policy>
+T igamma_temme_large(T a, T x, const Policy& pol, boost::integral_constant<int, 113> const *)
+{
+   BOOST_MATH_STD_USING // ADL of std functions
+   T sigma = (x - a) / a;
+   T phi = -boost::math::log1pmx(sigma, pol);
+   T y = a * phi;
+   T z = sqrt(2 * phi);
+   if(x < a)
+      z = -z;
+
+   T workspace[14];
+
+   static const T C0[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.333333333333333333333333333333333333),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.0833333333333333333333333333333333333),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.0148148148148148148148148148148148148),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.00115740740740740740740740740740740741),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.0003527336860670194003527336860670194),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000178755144032921810699588477366255144),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.391926317852243778169704095630021556e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.218544851067999216147364295512443661e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.185406221071515996070179883622956325e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.829671134095308600501624213166443227e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.17665952736826079304360054245742403e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.670785354340149858036939710029613572e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.102618097842403080425739573227252951e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.438203601845335318655297462244719123e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.914769958223679023418248817633113681e-9),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.255141939949462497668779537993887013e-10),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.583077213255042506746408945040035798e-10),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.243619480206674162436940696707789943e-10),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.502766928011417558909054985925744366e-11),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.110043920319561347708374174497293411e-12),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.337176326240098537882769884169200185e-12),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.13923887224181620659193661848957998e-12),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.285348938070474432039669099052828299e-13),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.513911183424257261899064580300494205e-15),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.197522882943494428353962401580710912e-14),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.809952115670456133407115668702575255e-15),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.165225312163981618191514820265351162e-15),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.253054300974788842327061090060267385e-17),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.116869397385595765888230876507793475e-16),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.477003704982048475822167804084816597e-17),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.969912605905623712420709685898585354e-18),
+   };
+   workspace[0] = tools::evaluate_polynomial(C0, z);
+
+   static const T C1[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.00185185185185185185185185185185185185),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.00347222222222222222222222222222222222),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.0026455026455026455026455026455026455),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000990226337448559670781893004115226337),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.000205761316872427983539094650205761317),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.401877572016460905349794238683127572e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.180985503344899778370285914867533523e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.76491609160811100846374214980916921e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.16120900894563446003775221882217767e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.464712780280743434226135033938722401e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.137863344691572095931187533077488877e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.575254560351770496402194531835048307e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.119516285997781473243076536699698169e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.175432417197476476237547551202312502e-10),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.100915437106004126274577504686681675e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.416279299184258263623372347219858628e-9),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.856390702649298063807431562579670208e-10),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.606721510160475861512701762169919581e-13),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.716249896481148539007961017165545733e-11),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.293318664377143711740636683615595403e-11),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.599669636568368872330374527568788909e-12),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.216717865273233141017100472779701734e-15),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.497833997236926164052815522048108548e-13),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.202916288237134247736694804325894226e-13),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.413125571381061004935108332558187111e-14),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.828651623988309644380188591057589316e-18),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.341003088693333279336339355910600992e-15),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.138541953028939715357034547426313703e-15),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.281234665322887466568860332727259483e-16),
+   };
+   workspace[1] = tools::evaluate_polynomial(C1, z);
+
+   static const T C2[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.0041335978835978835978835978835978836),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.00268132716049382716049382716049382716),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.000771604938271604938271604938271604938),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.200938786008230452674897119341563786e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000107366532263651605215391223621676297),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.529234488291201254164217127180090143e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.127606351886187277133779191392360117e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.34235787340961380741902003904747389e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.137219573090629332055943852926020279e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.629899213838005502290672234278391876e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.142806142060642417915846008822771748e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.204770984219908660149195854409200226e-9),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.140925299108675210532930244154315272e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.622897408492202203356394293530327112e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.136704883966171134992724380284402402e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.942835615901467819547711211663208075e-12),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.128722524000893180595479368872770442e-9),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.556459561343633211465414765894951439e-10),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.119759355463669810035898150310311343e-10),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.416897822518386350403836626692480096e-14),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.109406404278845944099299008640802908e-11),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.4662239946390135746326204922464679e-12),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.990510576390690597844122258212382301e-13),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.189318767683735145056885183170630169e-16),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.885922187259112726176031067028740667e-14),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.373782039804640545306560251777191937e-14),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.786883363903515525774088394065960751e-15),
+   };
+   workspace[2] = tools::evaluate_polynomial(C2, z);
+
+   static const T C3[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.000649434156378600823045267489711934156),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.000229472093621399176954732510288065844),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000469189494395255712128140111679206329),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.000267720632062838852962309752433209223),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.756180167188397641072538191879755666e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.239650511386729665193314027333231723e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.110826541153473023614770299726861227e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.567495282699159656749963105701560205e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.14230900732435883914551894470580433e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.278610802915281422405802158211174452e-10),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.16958404091930277289864168795820267e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.809946490538808236335278504852724081e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.191111684859736540606728140872727635e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.239286204398081179686413514022282056e-11),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.206201318154887984369925818486654549e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.946049666185513217375417988510192814e-9),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.215410497757749078380130268468744512e-9),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.138882333681390304603424682490735291e-13),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.218947616819639394064123400466489455e-10),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.979099895117168512568262802255883368e-11),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.217821918801809621153859472011393244e-11),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.62088195734079014258166361684972205e-16),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.212697836327973697696702537114614471e-12),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.934468879151743333127396765626749473e-13),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.204536712267828493249215913063207436e-13),
+   };
+   workspace[3] = tools::evaluate_polynomial(C3, z);
+
+   static const T C4[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000861888290916711698604702719929057378),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.00078403922172006662747403488144228885),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000299072480303190179733389609932819809),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.146384525788434181781232535690697556e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.664149821546512218665853782451862013e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.396836504717943466443123507595386882e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.113757269706784190980552042885831759e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.250749722623753280165221942390057007e-9),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.169541495365583060147164356781525752e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.890750753220530968882898422505515924e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.229293483400080487057216364891158518e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.295679413754404904696572852500004588e-10),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.288658297427087836297341274604184504e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.141897394378032193894774303903982717e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.344635804994648970659527720474194356e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.230245171745280671320192735850147087e-12),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.394092330280464052750697640085291799e-9),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.186023389685045019134258533045185639e-9),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.435632300505661804380678327446262424e-10),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.127860010162962312660550463349930726e-14),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.467927502665791946200382739991760062e-11),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.214924647061348285410535341910721086e-11),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.490881561480965216323649688463984082e-12),
+   };
+   workspace[4] = tools::evaluate_polynomial(C4, z);
+
+   static const T C5[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000336798553366358150308767592718210002),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.697281375836585777429398828575783308e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.00027727532449593920787336425196507501),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000199325705161888477003360405280844238),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.679778047793720783881640176604435742e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.141906292064396701483392727105575757e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.135940481897686932784583938837504469e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.80184702563342015397192571980419684e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.229148117650809517038048790128781806e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.325247355129845395166230137750005047e-9),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.346528464910852649559195496827579815e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.184471871911713432765322367374920978e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.482409670378941807563762631738989002e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.179894667217435153025754291716644314e-13),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.630619450001352343517516981425944698e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.316241762877456793773762181540969623e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.784092425369742929000839303523267545e-9),
+   };
+   workspace[5] = tools::evaluate_polynomial(C5, z);
+
+   static const T C6[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.00053130793646399222316574854297762391),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000592166437353693882864836225604401187),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.000270878209671804482771279183488328692),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.790235323266032787212032944390816666e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.815396936756196875092890088464682624e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.561168275310624965003775619041471695e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.183291165828433755673259749374098313e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.307961345060330478256414192546677006e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.346515536880360908673728529745376913e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.202913273960586037269527254582695285e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.578879286314900370889997586203187687e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.233863067382665698933480579231637609e-12),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.88286007463304835250508524317926246e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.474359588804081278032150770595852426e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.125454150207103824457130611214783073e-7),
+   };
+   workspace[6] = tools::evaluate_polynomial(C6, z);
+
+   static const T C7[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.000344367606892377671254279625108523655),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.517179090826059219337057843002058823e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000334931610811422363116635090580012327),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.000281269515476323702273722110707777978),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000109765822446847310235396824500789005),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.127410090954844853794579954588107623e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.277444515115636441570715073933712622e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.182634888057113326614324442681892723e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.578769494973505239894178121070843383e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.493875893393627039981813418398565502e-9),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.105953670140260427338098566209633945e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.616671437611040747858836254004890765e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.175629733590604619378669693914265388e-6),
+   };
+   workspace[7] = tools::evaluate_polynomial(C7, z);
+
+   static const T C8[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000652623918595309418922034919726622692),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.000839498720672087279993357516764983445),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000438297098541721005061087953050560377),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.696909145842055197136911097362072702e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.00016644846642067547837384572662326101),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000127835176797692185853344001461664247),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.462995326369130429061361032704489636e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.455790986792270771162749294232219616e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.105952711258051954718238500312872328e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.678334290486516662273073740749269432e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.210754766662588042469972680229376445e-5),
+   };
+   workspace[8] = tools::evaluate_polynomial(C8, z);
+
+   static const T C9[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000596761290192746250124390067179459605),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.720489541602001055908571930225015052e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.000678230883766732836161951166000673426),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000640147526026275845100045652582354779),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.000277501076343287044992374518205845463),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.181970083804651510461686554030325202e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.847950711706850318239732559632810086e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.610519208250153101764709122740859458e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.210739201834048624082975255893773306e-4),
+   };
+   workspace[9] = tools::evaluate_polynomial(C9, z);
+
+   static const T C10[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.00133244544948006563712694993432717968),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.00191443849856547752650089885832852254),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.0011089369134596637339607446329267522),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.993240412264229896742295262075817566e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000508745012930931989848393025305956774),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.00042735056665392884328432271160040444),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.000168588537679107988033552814662382059),
+   };
+   workspace[10] = tools::evaluate_polynomial(C10, z);
+
+   static const T C11[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.00157972766073083495908785631307733022),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.000162516262783915816898635123980270998),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.00206334210355432762645284467690276817),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.00213896861856890981541061922797693947),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.00101085593912630031708085801712479376),
+   };
+   workspace[11] = tools::evaluate_polynomial(C11, z);
+
+   static const T C12[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.00407251211951401664727281097914544601),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.00640336283380806979482363809026579583),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.00404101610816766177473974858518094879),
+   };
+   workspace[12] = tools::evaluate_polynomial(C12, z);
+   workspace[13] = -0.0059475779383993002845382844736066323L;
+
+   T result = tools::evaluate_polynomial(workspace, T(1/a));
+   result *= exp(-y) / sqrt(2 * constants::pi<T>() * a);
+   if(x < a)
+      result = -result;
+
+   result += boost::math::erfc(sqrt(y), pol) / 2;
+
+   return result;
+}
+
+}  // namespace detail
+}  // namespace math
+}  // namespace math
+
+
+#endif // BOOST_MATH_DETAIL_IGAMMA_LARGE
+
diff --git a/ThirdParty/boost/math/special_functions/detail/lanczos_sse2.hpp b/ThirdParty/boost/math/special_functions/detail/lanczos_sse2.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2ebde18e09f9f051566ed91fa4b676cb2fedae94
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/detail/lanczos_sse2.hpp
@@ -0,0 +1,238 @@
+//  (C) Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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_SPECIAL_FUNCTIONS_LANCZOS_SSE2
+#define BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS_SSE2
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <emmintrin.h>
+
+#if defined(__GNUC__) || defined(__PGI) || defined(__SUNPRO_CC)
+#define ALIGN16 __attribute__((__aligned__(16)))
+#else
+#define ALIGN16 __declspec(align(16))
+#endif
+
+namespace boost{ namespace math{ namespace lanczos{
+
+template <>
+inline double lanczos13m53::lanczos_sum<double>(const double& x)
+{
+   static const ALIGN16 double coeff[26] = {
+      static_cast<double>(2.506628274631000270164908177133837338626L),
+      static_cast<double>(1u),
+      static_cast<double>(210.8242777515793458725097339207133627117L),
+      static_cast<double>(66u),
+      static_cast<double>(8071.672002365816210638002902272250613822L),
+      static_cast<double>(1925u),
+      static_cast<double>(186056.2653952234950402949897160456992822L),
+      static_cast<double>(32670u),
+      static_cast<double>(2876370.628935372441225409051620849613599L),
+      static_cast<double>(357423u),
+      static_cast<double>(31426415.58540019438061423162831820536287L),
+      static_cast<double>(2637558u),
+      static_cast<double>(248874557.8620541565114603864132294232163L),
+      static_cast<double>(13339535u),
+      static_cast<double>(1439720407.311721673663223072794912393972L),
+      static_cast<double>(45995730u),
+      static_cast<double>(6039542586.35202800506429164430729792107L),
+      static_cast<double>(105258076u),
+      static_cast<double>(17921034426.03720969991975575445893111267L),
+      static_cast<double>(150917976u),
+      static_cast<double>(35711959237.35566804944018545154716670596L),
+      static_cast<double>(120543840u),
+      static_cast<double>(42919803642.64909876895789904700198885093L),
+      static_cast<double>(39916800u),
+      static_cast<double>(23531376880.41075968857200767445163675473L),
+      static_cast<double>(0u)
+   };
+
+   static const double lim = 4.31965e+25; // By experiment, the largest x for which the SSE2 code does not go bad.
+
+   if (x > lim)
+   {
+      double z = 1 / x;
+      return ((((((((((((coeff[24] * z + coeff[22]) * z + coeff[20]) * z + coeff[18]) * z + coeff[16]) * z + coeff[14]) * z + coeff[12]) * z + coeff[10]) * z + coeff[8]) * z + coeff[6]) * z + coeff[4]) * z + coeff[2]) * z + coeff[0]) / ((((((((((((coeff[25] * z + coeff[23]) * z + coeff[21]) * z + coeff[19]) * z + coeff[17]) * z + coeff[15]) * z + coeff[13]) * z + coeff[11]) * z + coeff[9]) * z + coeff[7]) * z + coeff[5]) * z + coeff[3]) * z + coeff[1]);
+   }
+
+   __m128d vx = _mm_load1_pd(&x);
+   __m128d sum_even = _mm_load_pd(coeff);
+   __m128d sum_odd = _mm_load_pd(coeff+2);
+   __m128d nc_odd, nc_even;
+   __m128d vx2 = _mm_mul_pd(vx, vx);
+
+   sum_even = _mm_mul_pd(sum_even, vx2);
+   nc_even = _mm_load_pd(coeff + 4);
+   sum_odd = _mm_mul_pd(sum_odd, vx2);
+   nc_odd = _mm_load_pd(coeff + 6);
+   sum_even = _mm_add_pd(sum_even, nc_even);
+   sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+   sum_even = _mm_mul_pd(sum_even, vx2);
+   nc_even = _mm_load_pd(coeff + 8);
+   sum_odd = _mm_mul_pd(sum_odd, vx2);
+   nc_odd = _mm_load_pd(coeff + 10);
+   sum_even = _mm_add_pd(sum_even, nc_even);
+   sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+   sum_even = _mm_mul_pd(sum_even, vx2);
+   nc_even = _mm_load_pd(coeff + 12);
+   sum_odd = _mm_mul_pd(sum_odd, vx2);
+   nc_odd = _mm_load_pd(coeff + 14);
+   sum_even = _mm_add_pd(sum_even, nc_even);
+   sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+   sum_even = _mm_mul_pd(sum_even, vx2);
+   nc_even = _mm_load_pd(coeff + 16);
+   sum_odd = _mm_mul_pd(sum_odd, vx2);
+   nc_odd = _mm_load_pd(coeff + 18);
+   sum_even = _mm_add_pd(sum_even, nc_even);
+   sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+   sum_even = _mm_mul_pd(sum_even, vx2);
+   nc_even = _mm_load_pd(coeff + 20);
+   sum_odd = _mm_mul_pd(sum_odd, vx2);
+   nc_odd = _mm_load_pd(coeff + 22);
+   sum_even = _mm_add_pd(sum_even, nc_even);
+   sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+   sum_even = _mm_mul_pd(sum_even, vx2);
+   nc_even = _mm_load_pd(coeff + 24);
+   sum_odd = _mm_mul_pd(sum_odd, vx);
+   sum_even = _mm_add_pd(sum_even, nc_even);
+   sum_even = _mm_add_pd(sum_even, sum_odd);
+
+
+   double ALIGN16 t[2];
+   _mm_store_pd(t, sum_even);
+   
+   return t[0] / t[1];
+}
+
+template <>
+inline double lanczos13m53::lanczos_sum_expG_scaled<double>(const double& x)
+{
+   static const ALIGN16 double coeff[26] = {
+         static_cast<double>(0.006061842346248906525783753964555936883222L),
+         static_cast<double>(1u),
+         static_cast<double>(0.5098416655656676188125178644804694509993L),
+         static_cast<double>(66u),
+         static_cast<double>(19.51992788247617482847860966235652136208L),
+         static_cast<double>(1925u),
+         static_cast<double>(449.9445569063168119446858607650988409623L),
+         static_cast<double>(32670u),
+         static_cast<double>(6955.999602515376140356310115515198987526L),
+         static_cast<double>(357423u),
+         static_cast<double>(75999.29304014542649875303443598909137092L),
+         static_cast<double>(2637558u),
+         static_cast<double>(601859.6171681098786670226533699352302507L),
+         static_cast<double>(13339535u),
+         static_cast<double>(3481712.15498064590882071018964774556468L),
+         static_cast<double>(45995730u),
+         static_cast<double>(14605578.08768506808414169982791359218571L),
+         static_cast<double>(105258076u),
+         static_cast<double>(43338889.32467613834773723740590533316085L),
+         static_cast<double>(150917976u),
+         static_cast<double>(86363131.28813859145546927288977868422342L),
+         static_cast<double>(120543840u),
+         static_cast<double>(103794043.1163445451906271053616070238554L),
+         static_cast<double>(39916800u),
+         static_cast<double>(56906521.91347156388090791033559122686859L),
+         static_cast<double>(0u)
+   };
+
+   static const double lim = 4.76886e+25; // By experiment, the largest x for which the SSE2 code does not go bad.
+
+   if (x > lim)
+   {
+      double z = 1 / x;
+      return ((((((((((((coeff[24] * z + coeff[22]) * z + coeff[20]) * z + coeff[18]) * z + coeff[16]) * z + coeff[14]) * z + coeff[12]) * z + coeff[10]) * z + coeff[8]) * z + coeff[6]) * z + coeff[4]) * z + coeff[2]) * z + coeff[0]) / ((((((((((((coeff[25] * z + coeff[23]) * z + coeff[21]) * z + coeff[19]) * z + coeff[17]) * z + coeff[15]) * z + coeff[13]) * z + coeff[11]) * z + coeff[9]) * z + coeff[7]) * z + coeff[5]) * z + coeff[3]) * z + coeff[1]);
+   }
+
+   __m128d vx = _mm_load1_pd(&x);
+   __m128d sum_even = _mm_load_pd(coeff);
+   __m128d sum_odd = _mm_load_pd(coeff+2);
+   __m128d nc_odd, nc_even;
+   __m128d vx2 = _mm_mul_pd(vx, vx);
+
+   sum_even = _mm_mul_pd(sum_even, vx2);
+   nc_even = _mm_load_pd(coeff + 4);
+   sum_odd = _mm_mul_pd(sum_odd, vx2);
+   nc_odd = _mm_load_pd(coeff + 6);
+   sum_even = _mm_add_pd(sum_even, nc_even);
+   sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+   sum_even = _mm_mul_pd(sum_even, vx2);
+   nc_even = _mm_load_pd(coeff + 8);
+   sum_odd = _mm_mul_pd(sum_odd, vx2);
+   nc_odd = _mm_load_pd(coeff + 10);
+   sum_even = _mm_add_pd(sum_even, nc_even);
+   sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+   sum_even = _mm_mul_pd(sum_even, vx2);
+   nc_even = _mm_load_pd(coeff + 12);
+   sum_odd = _mm_mul_pd(sum_odd, vx2);
+   nc_odd = _mm_load_pd(coeff + 14);
+   sum_even = _mm_add_pd(sum_even, nc_even);
+   sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+   sum_even = _mm_mul_pd(sum_even, vx2);
+   nc_even = _mm_load_pd(coeff + 16);
+   sum_odd = _mm_mul_pd(sum_odd, vx2);
+   nc_odd = _mm_load_pd(coeff + 18);
+   sum_even = _mm_add_pd(sum_even, nc_even);
+   sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+   sum_even = _mm_mul_pd(sum_even, vx2);
+   nc_even = _mm_load_pd(coeff + 20);
+   sum_odd = _mm_mul_pd(sum_odd, vx2);
+   nc_odd = _mm_load_pd(coeff + 22);
+   sum_even = _mm_add_pd(sum_even, nc_even);
+   sum_odd = _mm_add_pd(sum_odd, nc_odd);
+
+   sum_even = _mm_mul_pd(sum_even, vx2);
+   nc_even = _mm_load_pd(coeff + 24);
+   sum_odd = _mm_mul_pd(sum_odd, vx);
+   sum_even = _mm_add_pd(sum_even, nc_even);
+   sum_even = _mm_add_pd(sum_even, sum_odd);
+
+
+   double ALIGN16 t[2];
+   _mm_store_pd(t, sum_even);
+   
+   return t[0] / t[1];
+}
+
+#ifdef _MSC_VER
+
+BOOST_STATIC_ASSERT(sizeof(double) == sizeof(long double));
+
+template <>
+inline long double lanczos13m53::lanczos_sum<long double>(const long double& x)
+{
+   return lanczos_sum<double>(static_cast<double>(x));
+}
+template <>
+inline long double lanczos13m53::lanczos_sum_expG_scaled<long double>(const long double& x)
+{
+   return lanczos_sum_expG_scaled<double>(static_cast<double>(x));
+}
+#endif
+
+} // namespace lanczos
+} // namespace math
+} // namespace boost
+
+#undef ALIGN16
+
+#endif // BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS
+
+
+
+
+
diff --git a/ThirdParty/boost/math/special_functions/detail/lgamma_small.hpp b/ThirdParty/boost/math/special_functions/detail/lgamma_small.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9b8bf395aa6838e6609a5b7420aa340292b5f295
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/detail/lgamma_small.hpp
@@ -0,0 +1,532 @@
+//  (C) Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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_SPECIAL_FUNCTIONS_DETAIL_LGAMMA_SMALL
+#define BOOST_MATH_SPECIAL_FUNCTIONS_DETAIL_LGAMMA_SMALL
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/tools/big_constant.hpp>
+
+#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128)
+//
+// This is the only way we can avoid
+// warning: non-standard suffix on floating constant [-Wpedantic]
+// when building with -Wall -pedantic.  Neither __extension__
+// nor #pragma diagnostic ignored work :(
+//
+#pragma GCC system_header
+#endif
+
+namespace boost{ namespace math{ namespace detail{
+
+//
+// These need forward declaring to keep GCC happy:
+//
+template <class T, class Policy, class Lanczos>
+T gamma_imp(T z, const Policy& pol, const Lanczos& l);
+template <class T, class Policy>
+T gamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos& l);
+
+//
+// lgamma for small arguments:
+//
+template <class T, class Policy, class Lanczos>
+T lgamma_small_imp(T z, T zm1, T zm2, const boost::integral_constant<int, 64>&, const Policy& /* l */, const Lanczos&)
+{
+   // This version uses rational approximations for small
+   // values of z accurate enough for 64-bit mantissas
+   // (80-bit long doubles), works well for 53-bit doubles as well.
+   // Lanczos is only used to select the Lanczos function.
+
+   BOOST_MATH_STD_USING  // for ADL of std names
+   T result = 0;
+   if(z < tools::epsilon<T>())
+   {
+      result = -log(z);
+   }
+   else if((zm1 == 0) || (zm2 == 0))
+   {
+      // nothing to do, result is zero....
+   }
+   else if(z > 2)
+   {
+      //
+      // Begin by performing argument reduction until
+      // z is in [2,3):
+      //
+      if(z >= 3)
+      {
+         do
+         {
+            z -= 1;
+            zm2 -= 1;
+            result += log(z);
+         }while(z >= 3);
+         // Update zm2, we need it below:
+         zm2 = z - 2;
+      }
+
+      //
+      // Use the following form:
+      //
+      // lgamma(z) = (z-2)(z+1)(Y + R(z-2))
+      //
+      // where R(z-2) is a rational approximation optimised for
+      // low absolute error - as long as it's absolute error
+      // is small compared to the constant Y - then any rounding
+      // error in it's computation will get wiped out.
+      //
+      // R(z-2) has the following properties:
+      //
+      // At double: Max error found:                    4.231e-18
+      // At long double: Max error found:               1.987e-21
+      // Maximum Deviation Found (approximation error): 5.900e-24
+      //
+      static const T P[] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.180355685678449379109e-1)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.25126649619989678683e-1)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.494103151567532234274e-1)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.172491608709613993966e-1)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.259453563205438108893e-3)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.541009869215204396339e-3)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.324588649825948492091e-4))
+      };
+      static const T Q[] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1e1)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.196202987197795200688e1)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.148019669424231326694e1)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.541391432071720958364e0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.988504251128010129477e-1)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.82130967464889339326e-2)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.224936291922115757597e-3)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.223352763208617092964e-6))
+      };
+
+      static const float Y = 0.158963680267333984375e0f;
+
+      T r = zm2 * (z + 1);
+      T R = tools::evaluate_polynomial(P, zm2);
+      R /= tools::evaluate_polynomial(Q, zm2);
+
+      result +=  r * Y + r * R;
+   }
+   else
+   {
+      //
+      // If z is less than 1 use recurrence to shift to
+      // z in the interval [1,2]:
+      //
+      if(z < 1)
+      {
+         result += -log(z);
+         zm2 = zm1;
+         zm1 = z;
+         z += 1;
+      }
+      //
+      // Two approximations, on for z in [1,1.5] and
+      // one for z in [1.5,2]:
+      //
+      if(z <= 1.5)
+      {
+         //
+         // Use the following form:
+         //
+         // lgamma(z) = (z-1)(z-2)(Y + R(z-1))
+         //
+         // where R(z-1) is a rational approximation optimised for
+         // low absolute error - as long as it's absolute error
+         // is small compared to the constant Y - then any rounding
+         // error in it's computation will get wiped out.
+         //
+         // R(z-1) has the following properties:
+         //
+         // At double precision: Max error found:                1.230011e-17
+         // At 80-bit long double precision:   Max error found:  5.631355e-21
+         // Maximum Deviation Found:                             3.139e-021
+         // Expected Error Term:                                 3.139e-021
+
+         //
+         static const float Y = 0.52815341949462890625f;
+
+         static const T P[] = {
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.490622454069039543534e-1)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.969117530159521214579e-1)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.414983358359495381969e0)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.406567124211938417342e0)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.158413586390692192217e0)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.240149820648571559892e-1)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.100346687696279557415e-2))
+         };
+         static const T Q[] = {
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1e1)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.302349829846463038743e1)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.348739585360723852576e1)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.191415588274426679201e1)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.507137738614363510846e0)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.577039722690451849648e-1)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.195768102601107189171e-2))
+         };
+
+         T r = tools::evaluate_polynomial(P, zm1) / tools::evaluate_polynomial(Q, zm1);
+         T prefix = zm1 * zm2;
+
+         result += prefix * Y + prefix * r;
+      }
+      else
+      {
+         //
+         // Use the following form:
+         //
+         // lgamma(z) = (2-z)(1-z)(Y + R(2-z))
+         //
+         // where R(2-z) is a rational approximation optimised for
+         // low absolute error - as long as it's absolute error
+         // is small compared to the constant Y - then any rounding
+         // error in it's computation will get wiped out.
+         //
+         // R(2-z) has the following properties:
+         //
+         // At double precision, max error found:              1.797565e-17
+         // At 80-bit long double precision, max error found:  9.306419e-21
+         // Maximum Deviation Found:                           2.151e-021
+         // Expected Error Term:                               2.150e-021
+         //
+         static const float Y = 0.452017307281494140625f;
+
+         static const T P[] = {
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.292329721830270012337e-1)), 
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.144216267757192309184e0)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.142440390738631274135e0)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.542809694055053558157e-1)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.850535976868336437746e-2)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.431171342679297331241e-3))
+         };
+         static const T Q[] = {
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1e1)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.150169356054485044494e1)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.846973248876495016101e0)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.220095151814995745555e0)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.25582797155975869989e-1)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.100666795539143372762e-2)),
+            static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.827193521891290553639e-6))
+         };
+         T r = zm2 * zm1;
+         T R = tools::evaluate_polynomial(P, T(-zm2)) / tools::evaluate_polynomial(Q, T(-zm2));
+
+         result += r * Y + r * R;
+      }
+   }
+   return result;
+}
+template <class T, class Policy, class Lanczos>
+T lgamma_small_imp(T z, T zm1, T zm2, const boost::integral_constant<int, 113>&, const Policy& /* l */, const Lanczos&)
+{
+   //
+   // This version uses rational approximations for small
+   // values of z accurate enough for 113-bit mantissas
+   // (128-bit long doubles).
+   //
+   BOOST_MATH_STD_USING  // for ADL of std names
+   T result = 0;
+   if(z < tools::epsilon<T>())
+   {
+      result = -log(z);
+      BOOST_MATH_INSTRUMENT_CODE(result);
+   }
+   else if((zm1 == 0) || (zm2 == 0))
+   {
+      // nothing to do, result is zero....
+   }
+   else if(z > 2)
+   {
+      //
+      // Begin by performing argument reduction until
+      // z is in [2,3):
+      //
+      if(z >= 3)
+      {
+         do
+         {
+            z -= 1;
+            result += log(z);
+         }while(z >= 3);
+         zm2 = z - 2;
+      }
+      BOOST_MATH_INSTRUMENT_CODE(zm2);
+      BOOST_MATH_INSTRUMENT_CODE(z);
+      BOOST_MATH_INSTRUMENT_CODE(result);
+
+      //
+      // Use the following form:
+      //
+      // lgamma(z) = (z-2)(z+1)(Y + R(z-2))
+      //
+      // where R(z-2) is a rational approximation optimised for
+      // low absolute error - as long as it's absolute error
+      // is small compared to the constant Y - then any rounding
+      // error in it's computation will get wiped out.
+      //
+      // Maximum Deviation Found (approximation error)      3.73e-37
+
+      static const T P[] = {
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.018035568567844937910504030027467476655),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.013841458273109517271750705401202404195),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.062031842739486600078866923383017722399),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.052518418329052161202007865149435256093),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.01881718142472784129191838493267755758),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.0025104830367021839316463675028524702846),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.00021043176101831873281848891452678568311),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.00010249622350908722793327719494037981166),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.11381479670982006841716879074288176994e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.49999811718089980992888533630523892389e-6),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.70529798686542184668416911331718963364e-8)
+      };
+      static const T Q[] = {
+         BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 2.5877485070422317542808137697939233685),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 2.8797959228352591788629602533153837126),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 1.8030885955284082026405495275461180977),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.69774331297747390169238306148355428436),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.17261566063277623942044077039756583802),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.02729301254544230229429621192443000121),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.0026776425891195270663133581960016620433),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.00015244249160486584591370355730402168106),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.43997034032479866020546814475414346627e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.46295080708455613044541885534408170934e-7),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.93326638207459533682980757982834180952e-11),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.42316456553164995177177407325292867513e-13)
+      };
+
+      T R = tools::evaluate_polynomial(P, zm2);
+      R /= tools::evaluate_polynomial(Q, zm2);
+
+      static const float Y = 0.158963680267333984375F;
+
+      T r = zm2 * (z + 1);
+
+      result +=  r * Y + r * R;
+      BOOST_MATH_INSTRUMENT_CODE(result);
+   }
+   else
+   {
+      //
+      // If z is less than 1 use recurrence to shift to
+      // z in the interval [1,2]:
+      //
+      if(z < 1)
+      {
+         result += -log(z);
+         zm2 = zm1;
+         zm1 = z;
+         z += 1;
+      }
+      BOOST_MATH_INSTRUMENT_CODE(result);
+      BOOST_MATH_INSTRUMENT_CODE(z);
+      BOOST_MATH_INSTRUMENT_CODE(zm2);
+      //
+      // Three approximations, on for z in [1,1.35], [1.35,1.625] and [1.625,1]
+      //
+      if(z <= 1.35)
+      {
+         //
+         // Use the following form:
+         //
+         // lgamma(z) = (z-1)(z-2)(Y + R(z-1))
+         //
+         // where R(z-1) is a rational approximation optimised for
+         // low absolute error - as long as it's absolute error
+         // is small compared to the constant Y - then any rounding
+         // error in it's computation will get wiped out.
+         //
+         // R(z-1) has the following properties:
+         //
+         // Maximum Deviation Found (approximation error)            1.659e-36
+         // Expected Error Term (theoretical error)                  1.343e-36
+         // Max error found at 128-bit long double precision         1.007e-35
+         //
+         static const float Y = 0.54076099395751953125f;
+
+         static const T P[] = {
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.036454670944013329356512090082402429697),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.066235835556476033710068679907798799959),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.67492399795577182387312206593595565371),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -1.4345555263962411429855341651960000166),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -1.4894319559821365820516771951249649563),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.87210277668067964629483299712322411566),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.29602090537771744401524080430529369136),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.0561832587517836908929331992218879676),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.0053236785487328044334381502530383140443),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.00018629360291358130461736386077971890789),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.10164985672213178500790406939467614498e-6),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.13680157145361387405588201461036338274e-8)
+         };
+         static const T Q[] = {
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 4.9106336261005990534095838574132225599),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 10.258804800866438510889341082793078432),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 11.88588976846826108836629960537466889),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 8.3455000546999704314454891036700998428),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 3.6428823682421746343233362007194282703),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.97465989807254572142266753052776132252),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.15121052897097822172763084966793352524),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.012017363555383555123769849654484594893),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0003583032812720649835431669893011257277)
+         };
+
+         T r = tools::evaluate_polynomial(P, zm1) / tools::evaluate_polynomial(Q, zm1);
+         T prefix = zm1 * zm2;
+
+         result += prefix * Y + prefix * r;
+         BOOST_MATH_INSTRUMENT_CODE(result);
+      }
+      else if(z <= 1.625)
+      {
+         //
+         // Use the following form:
+         //
+         // lgamma(z) = (2-z)(1-z)(Y + R(2-z))
+         //
+         // where R(2-z) is a rational approximation optimised for
+         // low absolute error - as long as it's absolute error
+         // is small compared to the constant Y - then any rounding
+         // error in it's computation will get wiped out.
+         //
+         // R(2-z) has the following properties:
+         //
+         // Max error found at 128-bit long double precision  9.634e-36
+         // Maximum Deviation Found (approximation error)     1.538e-37
+         // Expected Error Term (theoretical error)           2.350e-38
+         //
+         static const float Y = 0.483787059783935546875f;
+
+         static const T P[] = {
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.017977422421608624353488126610933005432),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.18484528905298309555089509029244135703),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.40401251514859546989565001431430884082),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.40277179799147356461954182877921388182),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.21993421441282936476709677700477598816),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.069595742223850248095697771331107571011),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.012681481427699686635516772923547347328),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0012489322866834830413292771335113136034),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.57058739515423112045108068834668269608e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.8207548771933585614380644961342925976e-6)
+         };
+         static const T Q[] = {
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -2.9629552288944259229543137757200262073),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 3.7118380799042118987185957298964772755),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -2.5569815272165399297600586376727357187),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.0546764918220835097855665680632153367),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.26574021300894401276478730940980810831),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.03996289731752081380552901986471233462),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.0033398680924544836817826046380586480873),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00013288854760548251757651556792598235735),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.17194794958274081373243161848194745111e-5)
+         };
+         T r = zm2 * zm1;
+         T R = tools::evaluate_polynomial(P, T(0.625 - zm1)) / tools::evaluate_polynomial(Q, T(0.625 - zm1));
+
+         result += r * Y + r * R;
+         BOOST_MATH_INSTRUMENT_CODE(result);
+      }
+      else
+      {
+         //
+         // Same form as above.
+         //
+         // Max error found (at 128-bit long double precision) 1.831e-35
+         // Maximum Deviation Found (approximation error)      8.588e-36
+         // Expected Error Term (theoretical error)            1.458e-36
+         //
+         static const float Y = 0.443811893463134765625f;
+
+         static const T P[] = {
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.021027558364667626231512090082402429494),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.15128811104498736604523586803722368377),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.26249631480066246699388544451126410278),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.21148748610533489823742352180628489742),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.093964130697489071999873506148104370633),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.024292059227009051652542804957550866827),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.0036284453226534839926304745756906117066),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0002939230129315195346843036254392485984),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.11088589183158123733132268042570710338e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.13240510580220763969511741896361984162e-6)
+         };
+         static const T Q[] = {
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -2.4240003754444040525462170802796471996),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 2.4868383476933178722203278602342786002),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -1.4047068395206343375520721509193698547),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.47583809087867443858344765659065773369),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.09865724264554556400463655444270700132),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.012238223514176587501074150988445109735),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.00084625068418239194670614419707491797097),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.2796574430456237061420839429225710602e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.30202973883316730694433702165188835331e-6)
+         };
+         // (2 - x) * (1 - x) * (c + R(2 - x))
+         T r = zm2 * zm1;
+         T R = tools::evaluate_polynomial(P, T(-zm2)) / tools::evaluate_polynomial(Q, T(-zm2));
+
+         result += r * Y + r * R;
+         BOOST_MATH_INSTRUMENT_CODE(result);
+      }
+   }
+   BOOST_MATH_INSTRUMENT_CODE(result);
+   return result;
+}
+template <class T, class Policy, class Lanczos>
+T lgamma_small_imp(T z, T zm1, T zm2, const boost::integral_constant<int, 0>&, const Policy& pol, const Lanczos&)
+{
+   //
+   // No rational approximations are available because either
+   // T has no numeric_limits support (so we can't tell how
+   // many digits it has), or T has more digits than we know
+   // what to do with.... we do have a Lanczos approximation
+   // though, and that can be used to keep errors under control.
+   //
+   BOOST_MATH_STD_USING  // for ADL of std names
+   T result = 0;
+   if(z < tools::epsilon<T>())
+   {
+      result = -log(z);
+   }
+   else if(z < 0.5)
+   {
+      // taking the log of tgamma reduces the error, no danger of overflow here:
+      result = log(gamma_imp(z, pol, Lanczos()));
+   }
+   else if(z >= 3)
+   {
+      // taking the log of tgamma reduces the error, no danger of overflow here:
+      result = log(gamma_imp(z, pol, Lanczos()));
+   }
+   else if(z >= 1.5)
+   {
+      // special case near 2:
+      T dz = zm2;
+      result = dz * log((z + Lanczos::g() - T(0.5)) / boost::math::constants::e<T>());
+      result += boost::math::log1p(dz / (Lanczos::g() + T(1.5)), pol) * T(1.5);
+      result += boost::math::log1p(Lanczos::lanczos_sum_near_2(dz), pol);
+   }
+   else
+   {
+      // special case near 1:
+      T dz = zm1;
+      result = dz * log((z + Lanczos::g() - T(0.5)) / boost::math::constants::e<T>());
+      result += boost::math::log1p(dz / (Lanczos::g() + T(0.5)), pol) / 2;
+      result += boost::math::log1p(Lanczos::lanczos_sum_near_1(dz), pol);
+   }
+   return result;
+}
+
+}}} // namespaces
+
+#endif // BOOST_MATH_SPECIAL_FUNCTIONS_DETAIL_LGAMMA_SMALL
+
diff --git a/ThirdParty/boost/math/special_functions/detail/polygamma.hpp b/ThirdParty/boost/math/special_functions/detail/polygamma.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..10a04257a3adaef7cfa9fb32fee986e0f1ed9a70
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/detail/polygamma.hpp
@@ -0,0 +1,558 @@
+
+///////////////////////////////////////////////////////////////////////////////
+//  Copyright 2013 Nikhar Agrawal
+//  Copyright 2013 Christopher Kormanyos
+//  Copyright 2014 John Maddock
+//  Copyright 2013 Paul Bristow
+//  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_POLYGAMMA_DETAIL_2013_07_30_HPP_
+  #define _BOOST_POLYGAMMA_DETAIL_2013_07_30_HPP_
+
+#include <cmath>
+  #include <limits>
+  #include <boost/cstdint.hpp>
+  #include <boost/math/policies/policy.hpp>
+  #include <boost/math/special_functions/bernoulli.hpp>
+  #include <boost/math/special_functions/trunc.hpp>
+  #include <boost/math/special_functions/zeta.hpp>
+  #include <boost/math/special_functions/digamma.hpp>
+  #include <boost/math/special_functions/sin_pi.hpp>
+  #include <boost/math/special_functions/cos_pi.hpp>
+  #include <boost/math/special_functions/pow.hpp>
+  #include <boost/mpl/if.hpp>
+  #include <boost/mpl/int.hpp>
+  #include <boost/static_assert.hpp>
+  #include <boost/type_traits/is_convertible.hpp>
+
+#ifdef _MSC_VER
+#pragma once
+#pragma warning(push)
+#pragma warning(disable:4702) // Unreachable code (release mode only warning)
+#endif
+
+namespace boost { namespace math { namespace detail{
+
+  template<class T, class Policy>
+  T polygamma_atinfinityplus(const int n, const T& x, const Policy& pol, const char* function) // for large values of x such as for x> 400
+  {
+     // See http://functions.wolfram.com/GammaBetaErf/PolyGamma2/06/02/0001/
+     BOOST_MATH_STD_USING
+     //
+     // sum       == current value of accumulated sum.
+     // term      == value of current term to be added to sum.
+     // part_term == value of current term excluding the Bernoulli number part
+     //
+     if(n + x == x)
+     {
+        // x is crazy large, just concentrate on the first part of the expression and use logs:
+        if(n == 1) return 1 / x;
+        T nlx = n * log(x);
+        if((nlx < tools::log_max_value<T>()) && (n < (int)max_factorial<T>::value))
+           return ((n & 1) ? 1 : -1) * boost::math::factorial<T>(n - 1) * pow(x, -n);
+        else
+         return ((n & 1) ? 1 : -1) * exp(boost::math::lgamma(T(n), pol) - n * log(x));
+     }
+     T term, sum, part_term;
+     T x_squared = x * x;
+     //
+     // Start by setting part_term to:
+     //
+     // (n-1)! / x^(n+1)
+     //
+     // which is common to both the first term of the series (with k = 1)
+     // and to the leading part.  
+     // We can then get to the leading term by:
+     //
+     // part_term * (n + 2 * x) / 2
+     //
+     // and to the first term in the series 
+     // (excluding the Bernoulli number) by:
+     //
+     // part_term n * (n + 1) / (2x)
+     //
+     // If either the factorial would overflow,
+     // or the power term underflows, this just gets set to 0 and then we
+     // know that we have to use logs for the initial terms:
+     //
+     part_term = ((n > (int)boost::math::max_factorial<T>::value) && (T(n) * n > tools::log_max_value<T>())) 
+        ? T(0) : static_cast<T>(boost::math::factorial<T>(n - 1, pol) * pow(x, -n - 1));
+     if(part_term == 0)
+     {
+        // Either n is very large, or the power term underflows,
+        // set the initial values of part_term, term and sum via logs:
+        part_term = static_cast<T>(boost::math::lgamma(n, pol) - (n + 1) * log(x));
+        sum = exp(part_term + log(n + 2 * x) - boost::math::constants::ln_two<T>());
+        part_term += log(T(n) * (n + 1)) - boost::math::constants::ln_two<T>() - log(x);
+        part_term = exp(part_term);
+     }
+     else
+     {
+        sum = part_term * (n + 2 * x) / 2;
+        part_term *= (T(n) * (n + 1)) / 2;
+        part_term /= x;
+     }
+     //
+     // If the leading term is 0, so is the result:
+     //
+     if(sum == 0)
+        return sum;
+
+     for(unsigned k = 1;;)
+     {
+        term = part_term * boost::math::bernoulli_b2n<T>(k, pol);
+        sum += term;
+        //
+        // Normal termination condition:
+        //
+        if(fabs(term / sum) < tools::epsilon<T>())
+           break;
+        //
+        // Increment our counter, and move part_term on to the next value:
+        //
+        ++k;
+        part_term *= T(n + 2 * k - 2) * (n - 1 + 2 * k);
+        part_term /= (2 * k - 1) * 2 * k;
+        part_term /= x_squared;
+        //
+        // Emergency get out termination condition:
+        //
+        if(k > policies::get_max_series_iterations<Policy>())
+        {
+           return policies::raise_evaluation_error(function, "Series did not converge, closest value was %1%", sum, pol);
+        }
+     }
+     
+     if((n - 1) & 1)
+        sum = -sum;
+
+     return sum;
+  }
+
+  template<class T, class Policy>
+  T polygamma_attransitionplus(const int n, const T& x, const Policy& pol, const char* function)
+  {
+    // See: http://functions.wolfram.com/GammaBetaErf/PolyGamma2/16/01/01/0017/
+
+    // Use N = (0.4 * digits) + (4 * n) for target value for x:
+    BOOST_MATH_STD_USING
+    const int d4d  = static_cast<int>(0.4F * policies::digits_base10<T, Policy>());
+    const int N = d4d + (4 * n);
+    const int m    = n;
+    const int iter = N - itrunc(x);
+
+    if(iter > (int)policies::get_max_series_iterations<Policy>())
+       return policies::raise_evaluation_error<T>(function, ("Exceeded maximum series evaluations evaluating at n = " + boost::lexical_cast<std::string>(n) + " and x = %1%").c_str(), x, pol);
+
+    const int minus_m_minus_one = -m - 1;
+
+    T z(x);
+    T sum0(0);
+    T z_plus_k_pow_minus_m_minus_one(0);
+
+    // Forward recursion to larger x, need to check for overflow first though:
+    if(log(z + iter) * minus_m_minus_one > -tools::log_max_value<T>())
+    {
+       for(int k = 1; k <= iter; ++k)
+       {
+          z_plus_k_pow_minus_m_minus_one = pow(z, minus_m_minus_one);
+          sum0 += z_plus_k_pow_minus_m_minus_one;
+          z += 1;
+       }
+       sum0 *= boost::math::factorial<T>(n);
+    }
+    else
+    {
+       for(int k = 1; k <= iter; ++k)
+       {
+          T log_term = log(z) * minus_m_minus_one + boost::math::lgamma(T(n + 1), pol);
+          sum0 += exp(log_term);
+          z += 1;
+       }
+    }
+    if((n - 1) & 1)
+       sum0 = -sum0;
+
+    return sum0 + polygamma_atinfinityplus(n, z, pol, function);
+  }
+
+  template <class T, class Policy>
+  T polygamma_nearzero(int n, T x, const Policy& pol, const char* function)
+  {
+     BOOST_MATH_STD_USING
+     //
+     // If we take this expansion for polygamma: http://functions.wolfram.com/06.15.06.0003.02
+     // and substitute in this expression for polygamma(n, 1): http://functions.wolfram.com/06.15.03.0009.01
+     // we get an alternating series for polygamma when x is small in terms of zeta functions of
+     // integer arguments (which are easy to evaluate, at least when the integer is even).
+     //
+     // In order to avoid spurious overflow, save the n! term for later, and rescale at the end:
+     //
+     T scale = boost::math::factorial<T>(n, pol);
+     //
+     // "factorial_part" contains everything except the zeta function
+     // evaluations in each term:
+     //
+     T factorial_part = 1;
+     //
+     // "prefix" is what we'll be adding the accumulated sum to, it will
+     // be n! / z^(n+1), but since we're scaling by n! it's just 
+     // 1 / z^(n+1) for now:
+     //
+     T prefix = pow(x, n + 1);
+     if(prefix == 0)
+        return boost::math::policies::raise_overflow_error<T>(function, 0, pol);
+     prefix = 1 / prefix;
+     //
+     // First term in the series is necessarily < zeta(2) < 2, so
+     // ignore the sum if it will have no effect on the result anyway:
+     //
+     if(prefix > 2 / policies::get_epsilon<T, Policy>())
+        return ((n & 1) ? 1 : -1) * 
+         (tools::max_value<T>() / prefix < scale ? policies::raise_overflow_error<T>(function, 0, pol) : prefix * scale);
+     //
+     // As this is an alternating series we could accelerate it using 
+     // "Convergence Acceleration of Alternating Series",
+     // Henri Cohen, Fernando Rodriguez Villegas, and Don Zagier, Experimental Mathematics, 1999.
+     // In practice however, it appears not to make any difference to the number of terms
+     // required except in some edge cases which are filtered out anyway before we get here.
+     //
+     T sum = prefix;
+     for(unsigned k = 0;;)
+     {
+        // Get the k'th term:
+        T term = factorial_part * boost::math::zeta(T(k + n + 1), pol);
+        sum += term;
+        // Termination condition:
+        if(fabs(term) < fabs(sum * boost::math::policies::get_epsilon<T, Policy>()))
+           break;
+        //
+        // Move on k and factorial_part:
+        //
+        ++k;
+        factorial_part *= (-x * (n + k)) / k;
+        //
+        // Last chance exit:
+        //
+        if(k > policies::get_max_series_iterations<Policy>())
+           return policies::raise_evaluation_error<T>(function, "Series did not converge, best value is %1%", sum, pol);
+     }
+     //
+     // We need to multiply by the scale, at each stage checking for overflow:
+     //
+     if(boost::math::tools::max_value<T>() / scale < sum)
+        return boost::math::policies::raise_overflow_error<T>(function, 0, pol);
+     sum *= scale;
+     return n & 1 ? sum : T(-sum);
+  }
+
+  //
+  // Helper function which figures out which slot our coefficient is in
+  // given an angle multiplier for the cosine term of power:
+  //
+  template <class Table>
+  typename Table::value_type::reference dereference_table(Table& table, unsigned row, unsigned power)
+  {
+     return table[row][power / 2];
+  }
+
+
+
+  template <class T, class Policy>
+  T poly_cot_pi(int n, T x, T xc, const Policy& pol, const char* function)
+  {
+     BOOST_MATH_STD_USING
+     // Return n'th derivative of cot(pi*x) at x, these are simply
+     // tabulated for up to n = 9, beyond that it is possible to
+     // calculate coefficients as follows:
+     //
+     // The general form of each derivative is:
+     //
+     // pi^n * SUM{k=0, n} C[k,n] * cos^k(pi * x) * csc^(n+1)(pi * x)
+     //
+     // With constant C[0,1] = -1 and all other C[k,n] = 0;
+     // Then for each k < n+1:
+     // C[k-1, n+1]  -= k * C[k, n];
+     // C[k+1, n+1]  += (k-n-1) * C[k, n];
+     //
+     // Note that there are many different ways of representing this derivative thanks to
+     // the many trigonometric identies available.  In particular, the sum of powers of
+     // cosines could be replaced by a sum of cosine multiple angles, and indeed if you
+     // plug the derivative into Mathematica this is the form it will give.  The two
+     // forms are related via the Chebeshev polynomials of the first kind and
+     // T_n(cos(x)) = cos(n x).  The polynomial form has the great advantage that
+     // all the cosine terms are zero at half integer arguments - right where this
+     // function has it's minimum - thus avoiding cancellation error in this region.
+     //
+     // And finally, since every other term in the polynomials is zero, we can save
+     // space by only storing the non-zero terms.  This greatly complexifies
+     // subscripting the tables in the calculation, but halves the storage space
+     // (and complexity for that matter).
+     //
+     T s = fabs(x) < fabs(xc) ? boost::math::sin_pi(x, pol) : boost::math::sin_pi(xc, pol);
+     T c = boost::math::cos_pi(x, pol);
+     switch(n)
+     {
+     case 1:
+        return -constants::pi<T, Policy>() / (s * s);
+     case 2:
+     {
+        return 2 * constants::pi<T, Policy>() * constants::pi<T, Policy>() * c / boost::math::pow<3>(s, pol);
+     }
+     case 3:
+     {
+        int P[] = { -2, -4 };
+        return boost::math::pow<3>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<4>(s, pol);
+     }
+     case 4:
+     {
+        int P[] = { 16, 8 };
+        return boost::math::pow<4>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<5>(s, pol);
+     }
+     case 5:
+     {
+        int P[] = { -16, -88, -16 };
+        return boost::math::pow<5>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<6>(s, pol);
+     }
+     case 6:
+     {
+        int P[] = { 272, 416, 32 };
+        return boost::math::pow<6>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<7>(s, pol);
+     }
+     case 7:
+     {
+        int P[] = { -272, -2880, -1824, -64 };
+        return boost::math::pow<7>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<8>(s, pol);
+     }
+     case 8:
+     {
+        int P[] = { 7936, 24576, 7680, 128 };
+        return boost::math::pow<8>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<9>(s, pol);
+     }
+     case 9:
+     {
+        int P[] = { -7936, -137216, -185856, -31616, -256 };
+        return boost::math::pow<9>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<10>(s, pol);
+     }
+     case 10:
+     {
+        int P[] = { 353792, 1841152, 1304832, 128512, 512 };
+        return boost::math::pow<10>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<11>(s, pol);
+     }
+     case 11:
+     {
+        int P[] = { -353792, -9061376, -21253376, -8728576, -518656, -1024};
+        return boost::math::pow<11>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<12>(s, pol);
+     }
+     case 12:
+     {
+        int P[] = { 22368256, 175627264, 222398464, 56520704, 2084864, 2048 };
+        return boost::math::pow<12>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<13>(s, pol);
+     }
+#ifndef BOOST_NO_LONG_LONG
+     case 13:
+     {
+        long long P[] = { -22368256LL, -795300864LL, -2868264960LL, -2174832640LL, -357888000LL, -8361984LL, -4096 };
+        return boost::math::pow<13>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<14>(s, pol);
+     }
+     case 14:
+     {
+        long long P[] = { 1903757312LL, 21016670208LL, 41731645440LL, 20261765120LL, 2230947840LL, 33497088LL, 8192 };
+        return boost::math::pow<14>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<15>(s, pol);
+     }
+     case 15:
+     {
+        long long P[] = { -1903757312LL, -89702612992LL, -460858269696LL, -559148810240LL, -182172651520LL, -13754155008LL, -134094848LL, -16384 };
+        return boost::math::pow<15>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<16>(s, pol);
+     }
+     case 16:
+     {
+        long long P[] = { 209865342976LL, 3099269660672LL, 8885192097792LL, 7048869314560LL, 1594922762240LL, 84134068224LL, 536608768LL, 32768 };
+        return boost::math::pow<16>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<17>(s, pol);
+     }
+     case 17:
+     {
+        long long P[] = { -209865342976LL, -12655654469632LL, -87815735738368LL, -155964390375424LL, -84842998005760LL, -13684856848384LL, -511780323328LL, -2146926592LL, -65536 };
+        return boost::math::pow<17>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<18>(s, pol);
+     }
+     case 18:
+     {
+        long long P[] = { 29088885112832LL, 553753414467584LL, 2165206642589696LL, 2550316668551168LL, 985278548541440LL, 115620218667008LL, 3100738912256LL, 8588754944LL, 131072 };
+        return boost::math::pow<18>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<19>(s, pol);
+     }
+     case 19:
+     {
+        long long P[] = { -29088885112832LL, -2184860175433728LL, -19686087844429824LL, -48165109676113920LL, -39471306959486976LL, -11124607890751488LL, -965271355195392LL, -18733264797696LL, -34357248000LL, -262144 };
+        return boost::math::pow<19>(constants::pi<T, Policy>(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<20>(s, pol);
+     }
+     case 20:
+     {
+        long long P[] = { 4951498053124096LL, 118071834535526400LL, 603968063567560704LL, 990081991141490688LL, 584901762421358592LL, 122829335169859584LL, 7984436548730880LL, 112949304754176LL, 137433710592LL, 524288 };
+        return boost::math::pow<20>(constants::pi<T, Policy>(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<21>(s, pol);
+     }
+#endif
+     }
+
+     //
+     // We'll have to compute the coefficients up to n, 
+     // complexity is O(n^2) which we don't worry about for now
+     // as the values are computed once and then cached.
+     // However, if the final evaluation would have too many
+     // terms just bail out right away:
+     //
+     if((unsigned)n / 2u > policies::get_max_series_iterations<Policy>())
+        return policies::raise_evaluation_error<T>(function, "The value of n is so large that we're unable to compute the result in reasonable time, best guess is %1%", 0, pol);
+#ifdef BOOST_HAS_THREADS
+     static boost::detail::lightweight_mutex m;
+     boost::detail::lightweight_mutex::scoped_lock l(m);
+#endif
+     static int digits = tools::digits<T>();
+     static std::vector<std::vector<T> > table(1, std::vector<T>(1, T(-1)));
+
+     int current_digits = tools::digits<T>();
+
+     if(digits != current_digits)
+     {
+        // Oh my... our precision has changed!
+        table = std::vector<std::vector<T> >(1, std::vector<T>(1, T(-1)));
+        digits = current_digits;
+     }
+
+     int index = n - 1;
+
+     if(index >= (int)table.size())
+     {
+        for(int i = (int)table.size() - 1; i < index; ++i)
+        {
+           int offset = i & 1; // 1 if the first cos power is 0, otherwise 0.
+           int sin_order = i + 2;  // order of the sin term
+           int max_cos_order = sin_order - 1;  // largest order of the polynomial of cos terms
+           int max_columns = (max_cos_order - offset) / 2;  // How many entries there are in the current row.
+           int next_offset = offset ? 0 : 1;
+           int next_max_columns = (max_cos_order + 1 - next_offset) / 2;  // How many entries there will be in the next row
+           table.push_back(std::vector<T>(next_max_columns + 1, T(0)));
+
+           for(int column = 0; column <= max_columns; ++column)
+           {
+              int cos_order = 2 * column + offset;  // order of the cosine term in entry "column"
+              BOOST_ASSERT(column < (int)table[i].size());
+              BOOST_ASSERT((cos_order + 1) / 2 < (int)table[i + 1].size());
+              table[i + 1][(cos_order + 1) / 2] += ((cos_order - sin_order) * table[i][column]) / (sin_order - 1);
+              if(cos_order)
+                table[i + 1][(cos_order - 1) / 2] += (-cos_order * table[i][column]) / (sin_order - 1);
+           }
+        }
+
+     }
+     T sum = boost::math::tools::evaluate_even_polynomial(&table[index][0], c, table[index].size());
+     if(index & 1)
+        sum *= c;  // First coefficient is order 1, and really an odd polynomial.
+     if(sum == 0)
+        return sum;
+     //
+     // The remaining terms are computed using logs since the powers and factorials
+     // get real large real quick:
+     //
+     T power_terms = n * log(boost::math::constants::pi<T>());
+     if(s == 0)
+        return sum * boost::math::policies::raise_overflow_error<T>(function, 0, pol);
+     power_terms -= log(fabs(s)) * (n + 1);
+     power_terms += boost::math::lgamma(T(n));
+     power_terms += log(fabs(sum));
+
+     if(power_terms > boost::math::tools::log_max_value<T>())
+        return sum * boost::math::policies::raise_overflow_error<T>(function, 0, pol);
+
+     return exp(power_terms) * ((s < 0) && ((n + 1) & 1) ? -1 : 1) * boost::math::sign(sum);
+  }
+
+  template <class T, class Policy>
+  struct polygamma_initializer
+  {
+     struct init
+     {
+        init()
+        {
+           // Forces initialization of our table of coefficients and mutex:
+           boost::math::polygamma(30, T(-2.5f), Policy());
+        }
+        void force_instantiate()const{}
+     };
+     static const init initializer;
+     static void force_instantiate()
+     {
+        initializer.force_instantiate();
+     }
+  };
+
+  template <class T, class Policy>
+  const typename polygamma_initializer<T, Policy>::init polygamma_initializer<T, Policy>::initializer;
+  
+  template<class T, class Policy>
+  inline T polygamma_imp(const int n, T x, const Policy &pol)
+  {
+    BOOST_MATH_STD_USING
+    static const char* function = "boost::math::polygamma<%1%>(int, %1%)";
+    polygamma_initializer<T, Policy>::initializer.force_instantiate();
+    if(n < 0)
+       return policies::raise_domain_error<T>(function, "Order must be >= 0, but got %1%", static_cast<T>(n), pol);
+    if(x < 0)
+    {
+       if(floor(x) == x)
+       {
+          //
+          // Result is infinity if x is odd, and a pole error if x is even.
+          //
+          if(lltrunc(x) & 1)
+             return policies::raise_overflow_error<T>(function, 0, pol);
+          else
+             return policies::raise_pole_error<T>(function, "Evaluation at negative integer %1%", x, pol);
+       }
+       T z = 1 - x;
+       T result = polygamma_imp(n, z, pol) + constants::pi<T, Policy>() * poly_cot_pi(n, z, x, pol, function);
+       return n & 1 ? T(-result) : result;
+    }
+    //
+    // Limit for use of small-x-series is chosen
+    // so that the series doesn't go too divergent
+    // in the first few terms.  Ordinarily this
+    // would mean setting the limit to ~ 1 / n,
+    // but we can tolerate a small amount of divergence:
+    //
+    T small_x_limit = (std::min)(T(T(5) / n), T(0.25f));
+    if(x < small_x_limit)
+    {
+      return polygamma_nearzero(n, x, pol, function);
+    }
+    else if(x > 0.4F * policies::digits_base10<T, Policy>() + 4.0f * n)
+    {
+      return polygamma_atinfinityplus(n, x, pol, function);
+    }
+    else if(x == 1)
+    {
+       return (n & 1 ? 1 : -1) * boost::math::factorial<T>(n, pol) * boost::math::zeta(T(n + 1), pol);
+    }
+    else if(x == 0.5f)
+    {
+       T result = (n & 1 ? 1 : -1) * boost::math::factorial<T>(n, pol) * boost::math::zeta(T(n + 1), pol);
+       if(fabs(result) >= ldexp(tools::max_value<T>(), -n - 1))
+          return boost::math::sign(result) * policies::raise_overflow_error<T>(function, 0, pol);
+       result *= ldexp(T(1), n + 1) - 1;
+       return result;
+    }
+    else
+    {
+      return polygamma_attransitionplus(n, x, pol, function);
+    }
+  }
+
+} } } // namespace boost::math::detail
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // _BOOST_POLYGAMMA_DETAIL_2013_07_30_HPP_
+
diff --git a/ThirdParty/boost/math/special_functions/detail/unchecked_bernoulli.hpp b/ThirdParty/boost/math/special_functions/detail/unchecked_bernoulli.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4bb72d6cc160aa35ee33d30d2d57004fd9a865e4
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/detail/unchecked_bernoulli.hpp
@@ -0,0 +1,727 @@
+
+///////////////////////////////////////////////////////////////////////////////
+//  Copyright 2013 Nikhar Agrawal
+//  Copyright 2013 Christopher Kormanyos
+//  Copyright 2013 John Maddock
+//  Copyright 2013 Paul Bristow
+//  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_UNCHECKED_BERNOULLI_HPP
+#define BOOST_MATH_UNCHECKED_BERNOULLI_HPP
+
+#include <limits>
+#include <cmath>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/constants/constants.hpp>
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+
+#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
+#include <array>
+#else
+#include <boost/array.hpp>
+#endif
+
+
+namespace boost { namespace math { 
+   
+namespace detail {
+
+template <unsigned N>
+struct max_bernoulli_index
+{
+   BOOST_STATIC_CONSTANT(unsigned, value = 17);
+};
+
+template <>
+struct max_bernoulli_index<1>
+{
+   BOOST_STATIC_CONSTANT(unsigned, value = 32);
+};
+
+template <>
+struct max_bernoulli_index<2>
+{
+   BOOST_STATIC_CONSTANT(unsigned, value = 129);
+};
+
+template <>
+struct max_bernoulli_index<3>
+{
+   BOOST_STATIC_CONSTANT(unsigned, value = 1156);
+};
+
+template <>
+struct max_bernoulli_index<4>
+{
+   BOOST_STATIC_CONSTANT(unsigned, value = 11);
+};
+
+template <class T>
+struct bernoulli_imp_variant
+{
+   static const unsigned value = 
+      (std::numeric_limits<T>::max_exponent == 128)
+      && (std::numeric_limits<T>::radix == 2)
+      && (std::numeric_limits<T>::digits <= std::numeric_limits<float>::digits)
+      && (boost::is_convertible<float, T>::value) ? 1 :
+      (
+         (std::numeric_limits<T>::max_exponent == 1024)
+         && (std::numeric_limits<T>::radix == 2)
+         && (std::numeric_limits<T>::digits <= std::numeric_limits<double>::digits)
+         && (boost::is_convertible<double, T>::value) ? 2 :
+         (
+            (std::numeric_limits<T>::max_exponent == 16384)
+            && (std::numeric_limits<T>::radix == 2)
+            && (std::numeric_limits<T>::digits <= std::numeric_limits<long double>::digits)
+            && (boost::is_convertible<long double, T>::value) ? 3 : (!is_convertible<boost::int64_t, T>::value ? 4 : 0)
+         )
+      );
+};
+
+} // namespace detail
+
+template <class T>
+struct max_bernoulli_b2n : public detail::max_bernoulli_index<detail::bernoulli_imp_variant<T>::value>{};
+
+namespace detail{
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_imp(std::size_t n, const boost::integral_constant<int, 0>& )
+{
+#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
+   constexpr std::array<boost::int64_t, 1 + max_bernoulli_b2n<T>::value> numerators =
+#else
+   static const boost::array<boost::int64_t, 1 + max_bernoulli_b2n<T>::value> numerators =
+#endif
+   {{
+      boost::int64_t(            +1LL),
+      boost::int64_t(            +1LL),
+      boost::int64_t(            -1LL),
+      boost::int64_t(            +1LL),
+      boost::int64_t(            -1LL),
+      boost::int64_t(            +5LL),
+      boost::int64_t(          -691LL),
+      boost::int64_t(            +7LL),
+      boost::int64_t(         -3617LL),
+      boost::int64_t(        +43867LL),
+      boost::int64_t(       -174611LL),
+      boost::int64_t(       +854513LL),
+      boost::int64_t(    -236364091LL),
+      boost::int64_t(      +8553103LL),
+      boost::int64_t(  -23749461029LL),
+      boost::int64_t(+8615841276005LL),
+      boost::int64_t(-7709321041217LL),
+      boost::int64_t(+2577687858367LL)
+   }};
+
+#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
+   constexpr std::array<boost::int64_t, 1 + max_bernoulli_b2n<T>::value> denominators =
+#else
+   static const boost::array<boost::int64_t, 1 + max_bernoulli_b2n<T>::value> denominators =
+#endif
+   {{
+      boost::int64_t(      1LL),
+      boost::int64_t(      6LL),
+      boost::int64_t(     30LL),
+      boost::int64_t(     42LL),
+      boost::int64_t(     30LL),
+      boost::int64_t(     66LL),
+      boost::int64_t(   2730LL),
+      boost::int64_t(      6LL),
+      boost::int64_t(    510LL),
+      boost::int64_t(    798LL),
+      boost::int64_t(    330LL),
+      boost::int64_t(    138LL),
+      boost::int64_t(   2730LL),
+      boost::int64_t(      6LL),
+      boost::int64_t(    870LL),
+      boost::int64_t(  14322LL),
+      boost::int64_t(    510LL),
+      boost::int64_t(      6LL)
+   }};
+   return T(numerators[n]) / denominators[n];
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_imp(std::size_t n, const boost::integral_constant<int, 1>& )
+{
+#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
+   constexpr std::array<float, 1 + max_bernoulli_b2n<T>::value> bernoulli_data =
+#else
+   static const boost::array<float, 1 + max_bernoulli_b2n<T>::value> bernoulli_data =
+#endif
+   {{
+      +1.00000000000000000000000000000000000000000F,
+      +0.166666666666666666666666666666666666666667F,
+      -0.0333333333333333333333333333333333333333333F,
+      +0.0238095238095238095238095238095238095238095F,
+      -0.0333333333333333333333333333333333333333333F,
+      +0.0757575757575757575757575757575757575757576F,
+      -0.253113553113553113553113553113553113553114F,
+      +1.16666666666666666666666666666666666666667F,
+      -7.09215686274509803921568627450980392156863F,
+      +54.9711779448621553884711779448621553884712F,
+      -529.124242424242424242424242424242424242424F,
+      +6192.12318840579710144927536231884057971014F,
+      -86580.2531135531135531135531135531135531136F,
+      +1.42551716666666666666666666666666666666667e6F,
+      -2.72982310678160919540229885057471264367816e7F,
+      +6.01580873900642368384303868174835916771401e8F,
+      -1.51163157670921568627450980392156862745098e10F,
+      +4.29614643061166666666666666666666666666667e11F,
+      -1.37116552050883327721590879485616327721591e13F,
+      +4.88332318973593166666666666666666666666667e14F,
+      -1.92965793419400681486326681448632668144863e16F,
+      +8.41693047573682615000553709856035437430786e17F,
+      -4.03380718540594554130768115942028985507246e19F,
+      +2.11507486380819916056014539007092198581560e21F,
+      -1.20866265222965259346027311937082525317819e23F,
+      +7.50086674607696436685572007575757575757576e24F,
+      -5.03877810148106891413789303052201257861635e26F,
+      +3.65287764848181233351104308429711779448622e28F,
+      -2.84987693024508822262691464329106781609195e30F,
+      +2.38654274996836276446459819192192149717514e32F,
+      -2.13999492572253336658107447651910973926742e34F,
+      +2.05009757234780975699217330956723102516667e36F,
+      -2.09380059113463784090951852900279701847092e38F,
+   }};
+
+   return bernoulli_data[n];
+}
+
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_imp(std::size_t n, const boost::integral_constant<int, 2>& )
+{
+#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
+   constexpr std::array<double, 1 + max_bernoulli_b2n<T>::value> bernoulli_data =
+#else
+   static const boost::array<double, 1 + max_bernoulli_b2n<T>::value> bernoulli_data =
+#endif
+   {{
+      +1.00000000000000000000000000000000000000000,
+      +0.166666666666666666666666666666666666666667,
+      -0.0333333333333333333333333333333333333333333,
+      +0.0238095238095238095238095238095238095238095,
+      -0.0333333333333333333333333333333333333333333,
+      +0.0757575757575757575757575757575757575757576,
+      -0.253113553113553113553113553113553113553114,
+      +1.16666666666666666666666666666666666666667,
+      -7.09215686274509803921568627450980392156863,
+      +54.9711779448621553884711779448621553884712,
+      -529.124242424242424242424242424242424242424,
+      +6192.12318840579710144927536231884057971014,
+      -86580.2531135531135531135531135531135531136,
+      +1.42551716666666666666666666666666666666667e6,
+      -2.72982310678160919540229885057471264367816e7,
+      +6.01580873900642368384303868174835916771401e8,
+      -1.51163157670921568627450980392156862745098e10,
+      +4.29614643061166666666666666666666666666667e11,
+      -1.37116552050883327721590879485616327721591e13,
+      +4.88332318973593166666666666666666666666667e14,
+      -1.92965793419400681486326681448632668144863e16,
+      +8.41693047573682615000553709856035437430786e17,
+      -4.03380718540594554130768115942028985507246e19,
+      +2.11507486380819916056014539007092198581560e21,
+      -1.20866265222965259346027311937082525317819e23,
+      +7.50086674607696436685572007575757575757576e24,
+      -5.03877810148106891413789303052201257861635e26,
+      +3.65287764848181233351104308429711779448622e28,
+      -2.84987693024508822262691464329106781609195e30,
+      +2.38654274996836276446459819192192149717514e32,
+      -2.13999492572253336658107447651910973926742e34,
+      +2.05009757234780975699217330956723102516667e36,
+      -2.09380059113463784090951852900279701847092e38,
+      +2.27526964884635155596492603527692645814700e40,
+      -2.62577102862395760473030497361582020814490e42,
+      +3.21250821027180325182047923042649852435219e44,
+      -4.15982781667947109139170744952623589366896e46,
+      +5.69206954820352800238834562191210586444805e48,
+      -8.21836294197845756922906534686173330145509e50,
+      +1.25029043271669930167323398297028955241772e53,
+      -2.00155832332483702749253291988132987687242e55,
+      +3.36749829153643742333966769033387530162196e57,
+      -5.94709705031354477186604968440515408405791e59,
+      +1.10119103236279775595641307904376916046305e62,
+      -2.13552595452535011886583850190410656789733e64,
+      +4.33288969866411924196166130593792062184514e66,
+      -9.18855282416693282262005552155018971389604e68,
+      +2.03468967763290744934550279902200200659751e71,
+      -4.70038339580357310785752555350060606545967e73,
+      +1.13180434454842492706751862577339342678904e76,
+      -2.83822495706937069592641563364817647382847e78,
+      +7.40642489796788506297508271409209841768797e80,
+      -2.00964548027566044834656196727153631868673e83,
+      +5.66571700508059414457193460305193569614195e85,
+      -1.65845111541362169158237133743199123014950e88,
+      +5.03688599504923774192894219151801548124424e90,
+      -1.58614682376581863693634015729664387827410e93,
+      +5.17567436175456269840732406825071225612408e95,
+      -1.74889218402171173396900258776181591451415e98,
+      +6.11605199949521852558245252642641677807677e100,
+      -2.21227769127078349422883234567129324455732e103,
+      +8.27227767987709698542210624599845957312047e105,
+      -3.19589251114157095835916343691808148735263e108,
+      +1.27500822233877929823100243029266798669572e111,
+      -5.25009230867741338994028246245651754469199e113,
+      +2.23018178942416252098692981988387281437383e116,
+      -9.76845219309552044386335133989802393011669e118,
+      +4.40983619784529542722726228748131691918758e121,
+      -2.05085708864640888397293377275830154864566e124,
+      +9.82144332797912771075729696020975210414919e126,
+      -4.84126007982088805087891967099634127611305e129,
+      +2.45530888014809826097834674040886903996737e132,
+      -1.28069268040847475487825132786017857218118e135,
+      +6.86761671046685811921018885984644004360924e137,
+      -3.78464685819691046949789954163795568144895e140,
+      +2.14261012506652915508713231351482720966602e143,
+      -1.24567271371836950070196429616376072194583e146,
+      +7.43457875510001525436796683940520613117807e148,
+      -4.55357953046417048940633332233212748767721e151,
+      +2.86121128168588683453638472510172325229190e154,
+      -1.84377235520338697276882026536287854875414e157,
+      +1.21811545362210466995013165065995213558174e160,
+      -8.24821871853141215484818457296893447301419e162,
+      +5.72258779378329433296516498142978615918685e165,
+      -4.06685305250591047267679693831158655602196e168,
+      +2.95960920646420500628752695815851870426379e171,
+      -2.20495225651894575090311752273445984836379e174,
+      +1.68125970728895998058311525151360665754464e177,
+      -1.31167362135569576486452806355817153004431e180,
+      +1.04678940094780380821832853929823089643829e183,
+      -8.54328935788337077185982546299082774593270e185,
+      +7.12878213224865423522884066771438224721245e188,
+      -6.08029314555358993000847118686477458461988e191,
+      +5.29967764248499239300942910043247266228490e194,
+      -4.71942591687458626443646229013379911103761e197,
+      +4.29284137914029810894168296541074669045521e200,
+      -3.98767449682322074434477655542938795106651e203,
+      +3.78197804193588827138944181161393327898220e206,
+      -3.66142336836811912436858082151197348755196e209,
+      +3.61760902723728623488554609298914089477541e212,
+      -3.64707726451913543621383088655499449048682e215,
+      +3.75087554364544090983452410104814189306842e218,
+      -3.93458672964390282694891288533713429355657e221,
+      +4.20882111481900820046571171111494898242731e224,
+      -4.59022962206179186559802940573325591059371e227,
+      +5.10317257726295759279198185106496768539760e230,
+      -5.78227623036569554015377271242917142512200e233,
+      +6.67624821678358810322637794412809363451080e236,
+      -7.85353076444504163225916259639312444428230e239,
+      +9.41068940670587255245443288258762485293948e242,
+      -1.14849338734651839938498599206805592548354e246,
+      +1.42729587428487856771416320087122499897180e249,
+      -1.80595595869093090142285728117654560926719e252,
+      +2.32615353076608052161297985184708876161736e255,
+      -3.04957517154995947681942819261542593785327e258,
+      +4.06858060764339734424012124124937318633684e261,
+      -5.52310313219743616252320044093186392324280e264,
+      +7.62772793964343924869949690204961215533859e267,
+      -1.07155711196978863132793524001065396932667e271,
+      +1.53102008959691884453440916153355334355847e274,
+      -2.22448916821798346676602348865048510824835e277,
+      +3.28626791906901391668189736436895275365183e280,
+      -4.93559289559603449020711938191575963496999e283,
+      +7.53495712008325067212266049779283956727824e286,
+      -1.16914851545841777278088924731655041783900e290,
+      +1.84352614678389394126646201597702232396492e293,
+      -2.95368261729680829728014917350525183485207e296,
+      +4.80793212775015697668878704043264072227967e299,
+      -7.95021250458852528538243631671158693036798e302,
+      +1.33527841873546338750122832017820518292039e306
+   }};
+
+   return bernoulli_data[n];
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_imp(std::size_t n, const boost::integral_constant<int, 3>& )
+{
+#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
+   constexpr std::array<long double, 1 + max_bernoulli_b2n<T>::value> bernoulli_data =
+#else
+   static const boost::array<long double, 1 + max_bernoulli_b2n<T>::value> bernoulli_data =
+#endif
+   {{
+      +1.00000000000000000000000000000000000000000L,
+      +0.166666666666666666666666666666666666666667L,
+      -0.0333333333333333333333333333333333333333333L,
+      +0.0238095238095238095238095238095238095238095L,
+      -0.0333333333333333333333333333333333333333333L,
+      +0.0757575757575757575757575757575757575757576L,
+      -0.253113553113553113553113553113553113553114L,
+      +1.16666666666666666666666666666666666666667L,
+      -7.09215686274509803921568627450980392156863L,
+      +54.9711779448621553884711779448621553884712L,
+      -529.124242424242424242424242424242424242424L,
+      +6192.12318840579710144927536231884057971014L,
+      -86580.2531135531135531135531135531135531136L,
+      +1.42551716666666666666666666666666666666667E6L,
+      -2.72982310678160919540229885057471264367816E7L,
+      +6.01580873900642368384303868174835916771401E8L,
+      -1.51163157670921568627450980392156862745098E10L,
+      +4.29614643061166666666666666666666666666667E11L,
+      -1.37116552050883327721590879485616327721591E13L,
+      +4.88332318973593166666666666666666666666667E14L,
+      -1.92965793419400681486326681448632668144863E16L,
+      +8.41693047573682615000553709856035437430786E17L,
+      -4.03380718540594554130768115942028985507246E19L,
+      +2.11507486380819916056014539007092198581560E21L,
+      -1.20866265222965259346027311937082525317819E23L,
+      +7.50086674607696436685572007575757575757576E24L,
+      -5.03877810148106891413789303052201257861635E26L,
+      +3.65287764848181233351104308429711779448622E28L,
+      -2.84987693024508822262691464329106781609195E30L,
+      +2.38654274996836276446459819192192149717514E32L,
+      -2.13999492572253336658107447651910973926742E34L,
+      +2.05009757234780975699217330956723102516667E36L,
+      -2.09380059113463784090951852900279701847092E38L,
+      +2.27526964884635155596492603527692645814700E40L,
+      -2.62577102862395760473030497361582020814490E42L,
+      +3.21250821027180325182047923042649852435219E44L,
+      -4.15982781667947109139170744952623589366896E46L,
+      +5.69206954820352800238834562191210586444805E48L,
+      -8.21836294197845756922906534686173330145509E50L,
+      +1.25029043271669930167323398297028955241772E53L,
+      -2.00155832332483702749253291988132987687242E55L,
+      +3.36749829153643742333966769033387530162196E57L,
+      -5.94709705031354477186604968440515408405791E59L,
+      +1.10119103236279775595641307904376916046305E62L,
+      -2.13552595452535011886583850190410656789733E64L,
+      +4.33288969866411924196166130593792062184514E66L,
+      -9.18855282416693282262005552155018971389604E68L,
+      +2.03468967763290744934550279902200200659751E71L,
+      -4.70038339580357310785752555350060606545967E73L,
+      +1.13180434454842492706751862577339342678904E76L,
+      -2.83822495706937069592641563364817647382847E78L,
+      +7.40642489796788506297508271409209841768797E80L,
+      -2.00964548027566044834656196727153631868673E83L,
+      +5.66571700508059414457193460305193569614195E85L,
+      -1.65845111541362169158237133743199123014950E88L,
+      +5.03688599504923774192894219151801548124424E90L,
+      -1.58614682376581863693634015729664387827410E93L,
+      +5.17567436175456269840732406825071225612408E95L,
+      -1.74889218402171173396900258776181591451415E98L,
+      +6.11605199949521852558245252642641677807677E100L,
+      -2.21227769127078349422883234567129324455732E103L,
+      +8.27227767987709698542210624599845957312047E105L,
+      -3.19589251114157095835916343691808148735263E108L,
+      +1.27500822233877929823100243029266798669572E111L,
+      -5.25009230867741338994028246245651754469199E113L,
+      +2.23018178942416252098692981988387281437383E116L,
+      -9.76845219309552044386335133989802393011669E118L,
+      +4.40983619784529542722726228748131691918758E121L,
+      -2.05085708864640888397293377275830154864566E124L,
+      +9.82144332797912771075729696020975210414919E126L,
+      -4.84126007982088805087891967099634127611305E129L,
+      +2.45530888014809826097834674040886903996737E132L,
+      -1.28069268040847475487825132786017857218118E135L,
+      +6.86761671046685811921018885984644004360924E137L,
+      -3.78464685819691046949789954163795568144895E140L,
+      +2.14261012506652915508713231351482720966602E143L,
+      -1.24567271371836950070196429616376072194583E146L,
+      +7.43457875510001525436796683940520613117807E148L,
+      -4.55357953046417048940633332233212748767721E151L,
+      +2.86121128168588683453638472510172325229190E154L,
+      -1.84377235520338697276882026536287854875414E157L,
+      +1.21811545362210466995013165065995213558174E160L,
+      -8.24821871853141215484818457296893447301419E162L,
+      +5.72258779378329433296516498142978615918685E165L,
+      -4.06685305250591047267679693831158655602196E168L,
+      +2.95960920646420500628752695815851870426379E171L,
+      -2.20495225651894575090311752273445984836379E174L,
+      +1.68125970728895998058311525151360665754464E177L,
+      -1.31167362135569576486452806355817153004431E180L,
+      +1.04678940094780380821832853929823089643829E183L,
+      -8.54328935788337077185982546299082774593270E185L,
+      +7.12878213224865423522884066771438224721245E188L,
+      -6.08029314555358993000847118686477458461988E191L,
+      +5.29967764248499239300942910043247266228490E194L,
+      -4.71942591687458626443646229013379911103761E197L,
+      +4.29284137914029810894168296541074669045521E200L,
+      -3.98767449682322074434477655542938795106651E203L,
+      +3.78197804193588827138944181161393327898220E206L,
+      -3.66142336836811912436858082151197348755196E209L,
+      +3.61760902723728623488554609298914089477541E212L,
+      -3.64707726451913543621383088655499449048682E215L,
+      +3.75087554364544090983452410104814189306842E218L,
+      -3.93458672964390282694891288533713429355657E221L,
+      +4.20882111481900820046571171111494898242731E224L,
+      -4.59022962206179186559802940573325591059371E227L,
+      +5.10317257726295759279198185106496768539760E230L,
+      -5.78227623036569554015377271242917142512200E233L,
+      +6.67624821678358810322637794412809363451080E236L,
+      -7.85353076444504163225916259639312444428230E239L,
+      +9.41068940670587255245443288258762485293948E242L,
+      -1.14849338734651839938498599206805592548354E246L,
+      +1.42729587428487856771416320087122499897180E249L,
+      -1.80595595869093090142285728117654560926719E252L,
+      +2.32615353076608052161297985184708876161736E255L,
+      -3.04957517154995947681942819261542593785327E258L,
+      +4.06858060764339734424012124124937318633684E261L,
+      -5.52310313219743616252320044093186392324280E264L,
+      +7.62772793964343924869949690204961215533859E267L,
+      -1.07155711196978863132793524001065396932667E271L,
+      +1.53102008959691884453440916153355334355847E274L,
+      -2.22448916821798346676602348865048510824835E277L,
+      +3.28626791906901391668189736436895275365183E280L,
+      -4.93559289559603449020711938191575963496999E283L,
+      +7.53495712008325067212266049779283956727824E286L,
+      -1.16914851545841777278088924731655041783900E290L,
+      +1.84352614678389394126646201597702232396492E293L,
+      -2.95368261729680829728014917350525183485207E296L,
+      +4.80793212775015697668878704043264072227967E299L,
+      -7.95021250458852528538243631671158693036798E302L,
+      +1.33527841873546338750122832017820518292039E306L,
+#if LDBL_MAX_EXP == 16384
+      // Entries 260 - 600 http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C258%2C600%2C2}]
+      -2.277640649601959593875058983506938037019e309L, 
+      3.945184036046326234163525556422667595884e312L, 
+      -6.938525772130602106071724989641405550473e315L, 
+      1.238896367577564823729057820219210929986e319L, 
+      -2.245542599169309759499987966025604480745e322L, 
+      4.131213176073842359732511639489669404266e325L, 
+      -7.713581346815269584960928069762882771369e328L, 
+      1.461536066837669600638613788471335541313e332L, 
+      -2.809904606225532896862935642992712059631e335L, 
+      5.480957121318876639512096994413992284327e338L, 
+      -1.084573284087686110518125291186079616320e342L, 
+      2.176980775647663539729165173863716459962e345L, 
+      -4.431998786117553751947439433256752608068e348L, 
+      9.150625657715535047417756278073770096073e351L, 
+      -1.915867353003157351316577579148683133613e355L, 
+      4.067256303542212258698836003682016040629e358L, 
+      -8.754223791037736616228150209910348734629e361L, 
+      1.910173688735533667244373747124109379826e365L, 
+      -4.225001320265091714631115064713174404607e368L, 
+      9.471959352547827678466770796787503034505e371L, 
+      -2.152149973279986829719817376756088198573e375L, 
+      4.955485775334221051344839716507812871361e378L, 
+      -1.156225941759134696630956889716381968142e382L, 
+      2.733406597646137698610991926705098514017e385L, 
+      -6.546868135325176947099912523279938546333e388L, 
+      1.588524912441221472814692121069821695547e392L, 
+      -3.904354800861715180218598151050191841308e395L, 
+      9.719938686092045781827273411668132975319e398L, 
+      -2.450763621049522051234479737511375679283e402L, 
+      6.257892098396815305085674126334317095277e405L, 
+      -1.618113552083806592527989531636955084420e409L, 
+      4.236528795217618357348618613216833722648e412L, 
+      -1.123047068199051008086174989124136878992e416L, 
+      3.013971787525654770217283559392286666886e419L, 
+      -8.188437573221553030375681429202969070420e422L, 
+      2.251910591336716809153958146725775718707e426L, 
+      -6.268411292043789823075314151509139413399e429L, 
+      1.765990845202322642693572112511312471527e433L, 
+      -5.035154436231331651259071296731160882240e436L, 
+      1.452779356460483245253765356664402207266e440L, 
+      -4.241490890130137339052414960684151515166e443L, 
+      1.252966001692427774088293833338841893293e447L, 
+      -3.744830047478272947978103227876747240343e450L, 
+      1.132315806695710930595876001089232216024e454L, 
+      -3.463510845942701805991786197773934662578e457L, 
+      1.071643382649675572086865465873916611537e461L, 
+      -3.353824475439933688957233489984711465335e464L, 
+      1.061594257145875875963152734129803268488e468L, 
+      -3.398420969215528955528654193586189805265e471L, 
+      1.100192502000434096206138068020551065890e475L, 
+      -3.601686379213993374332690210094863486472e478L, 
+      1.192235170430164900533187239994513019475e482L, 
+      -3.990342751779668381699052942504119409180e485L, 
+      1.350281800938769780891258894167663309221e489L, 
+      -4.619325443466054312873093650888507562249e492L, 
+      1.597522243968586548227514639959727696694e496L, 
+      -5.584753729092155108530929002119620487652e499L, 
+      1.973443623104646193229794524759543752089e503L, 
+      -7.048295441989615807045620880311201930244e506L, 
+      2.544236702499719094591873151590280263560e510L, 
+      -9.281551595258615205927443367289948150345e513L, 
+      3.421757163154453657766296828520235351572e517L, 
+      -1.274733639384538364282697627345068947433e521L, 
+      4.798524805311016034711205886780460173566e524L, 
+      -1.825116948422858388787806917284878870034e528L, 
+      7.013667442807288452441777981425055613982e531L, 
+      -2.723003862685989740898815670978399383114e535L, 
+      1.068014853917260290630122222858884658850e539L, 
+      -4.231650952273697842269381683768681118533e542L, 
+      1.693650052202594386658903598564772900388e546L, 
+      -6.846944855806453360616258582310883597678e549L, 
+      2.795809132238082267120232174243715559601e553L, 
+      -1.153012972808983269106716828311318981951e557L, 
+      4.802368854268746357511997492039592697149e560L, 
+      -2.019995255271910836389761734035403905781e564L, 
+      8.580207235032617856059250643095019760968e567L, 
+      -3.680247942263468164408192134916355198549e571L, 
+      1.593924457586765331397457407661306895942e575L, 
+      -6.970267175232643679233530367569943057501e578L, 
+      3.077528087427698518703282907890556154309e582L, 
+      -1.371846760052887888926055417297342106614e586L, 
+      6.173627360829553396851763207025505289166e589L, 
+      -2.804703130495506384463249394043486916669e593L, 
+      1.286250900087150126167490951216207186092e597L, 
+      -5.954394420063617872366818601092036543220e600L, 
+      2.782297785278756426177542270854984091406e604L, 
+      -1.312214674935307746141207680066262384215e608L, 
+      6.246299145383554153167974732783934504370e611L, 
+      -3.000812007679574430883792565577444226490e615L, 
+      1.454904877136007844493861746476079537075e619L, 
+      -7.118558521873800304612781121044077357278e622L, 
+      3.514739820897817389472822276832677887997e626L, 
+      -1.751137068816377401163011262831890828437e630L, 
+      8.803498091818800678575314081978951179602e633L, 
+      -4.465612911700593572269200981612564161010e637L, 
+      2.285494565287530681465757798517033542888e641L, 
+      -1.180145168917737098025683613598595411329e645L, 
+      6.147941849198393232663105284575149616925e648L, 
+      -3.231069156963603593233679426198974663352e652L, 
+      1.713042725635435041806895849197608270935e656L, 
+      -9.161761363270648920537613435771882898051e659L, 
+      4.942675965960539112005679080810117766825e663L, 
+      -2.689684712697383518131267222872386600031e667L, 
+      1.476320014229917759615308193449511534656e671L, 
+      -8.173037740864781506597184122049453514594e674L, 
+      4.563462313190521363235182420178784459580e678L, 
+      -2.569790015236158475703055501886439298708e682L, 
+      1.459410219452119981958355737832022375085e686L, 
+      -8.358304882556983795372406183642486436653e689L, 
+      4.827305091483557818593092377664570208355e693L, 
+      -2.811394311081493166793414157061950132403e697L, 
+      1.651026863340675349245561261339568827739e701L, 
+      -9.776578579336866764167878646459810047899e704L, 
+      5.837207965197521880181236529616560780535e708L, 
+      -3.513938957938032127105389702846371181520e712L, 
+      2.132747371360190507595748444536911078788e716L, 
+      -1.305047363239192640729466563372665311602e720L, 
+      8.050825342678337497636292798039996484780e723L, 
+      -5.006884161223862543665524155681082112689e727L, 
+      3.139016066011452177570812014513491361235e731L, 
+      -1.983829535212711378291469356666001365873e735L, 
+      1.263822427649676371257598052486237628698e739L, 
+      -8.115678659900522918802121684491754629503e742L, 
+      5.252995164972075271667364371449050412435e746L, 
+      -3.427038125662404660056511738625477058135e750L, 
+      2.253446011834352733279946306835940729858e754L, 
+      -1.493407341897034717876962786798831719683e758L, 
+      9.974681322653365118752729509398728354442e761L, 
+      -6.714230142773850863927710112350816379426e765L, 
+      4.554668668931723346600337564274944733530e769L, 
+      -3.113635386023220127834102980385275379533e773L, 
+      2.144945411287666204679363498162954050208e777L, 
+      -1.488982121181387164932397544378555256016e781L, 
+      1.041537218854627455352298173588983048748e785L, 
+      -7.341073881786613676177562822942175683993e788L, 
+      5.213524272587199574980117351016322518428e792L, 
+      -3.730592531776514409283897139216167197989e796L, 
+      2.689592876341877079083449497724049500175e800L, 
+      -1.953643788231947582529884602972233135002e804L, 
+      1.429691073080500563348668321308878246277e808L, 
+      -1.054059177095488639836063073070536825675e812L, 
+      7.828919160938693948399336431565350676613e815L, 
+      -5.857884457184396382550955498026762014753e819L, 
+      4.415401588264172474136969345712659422380e823L, 
+      -3.352573884181287635796498822858109969161e827L, 
+      2.564210385719224000156548240934108974447e831L, 
+      -1.975534392116037602837941409848663077528e835L, 
+      1.533062123975940045180943006948008486466e839L, 
+      -1.198306160488763291730059994812781226903e843L, 
+      9.434034267770711698676321369174735725321e846L, 
+      -7.480619200038505368468483892246806488879e850L, 
+      5.974161898439971564124576801455052907638e854L, 
+      -4.805125663714699771668630995361572639386e858L, 
+      3.892332138028039952403812726744593073776e862L, 
+      -3.175276505779699340738548328810180869575e866L, 
+      2.608608681939322393581069188271626122519e870L, 
+      -2.158148554392732439392868052394994052628e874L, 
+      1.797993483301448477700600221980862686033e878L, 
+      -1.508407575089108597171576068862286462909e882L, 
+      1.274273406242459482708930389008701147244e886L, 
+      -1.083950475353171986748233157909397370193e890L, 
+      9.284292630726328432038470356821265395331e893L, 
+      -8.007012115449516364480417355063446317414e897L, 
+      6.952871948429568933888979915833266241471e901L, 
+      -6.078828929473797621198666799700739891205e905L, 
+      5.350908089710964244671334224708057812633e909L, 
+      -4.742168072503284973969982758434401589090e913L, 
+      4.231149239401967697257534662010605751136e917L, 
+      -3.800684612827828851942743291026898158947e921L, 
+      3.436984796314246158361599955909956583986e925L, 
+      -3.128930718993658356398482705317381808301e929L,
+      //
+      // 602-1300: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C602%2C1300%2C2}]
+      2.867524740577223817164663595437919813239e933L, -2.645462974939090580963101220449509725942e937L, 2.456800827789169780295419018499543141869e941L, -2.296690549725790064673528302231294870532e945L, 2.161174697699793265715182091764676666457e949L, -2.047023224586087259305754002882269123194e953L, 1.951604806042481282712736234132803700277e957L, -1.872785206668284042110390583158639495143e961L, 1.808847160923282257302788929692654262867e965L, -1.758427529634609613399327744595257497188e969L, 1.720468488019528147087036246754294757647e973L, -1.694180279355332648057740852839804839425e977L, 1.679013685251183870616469618951463869496e981L, -1.674640861433092946269144173974414945664e985L, 1.680943600147858322148767806987527412112e989L, -1.698008433134805056489370119323402510305e993L, 1.726128304411348354183882648263448448633e997L, -1.765810838736918108045764015629875016219e1001L, 1.817793526882665071123822455897912718293e1005L, -1.883066459765807128944897377914669600374e1009L, 1.962903588035940537938222992228124233567e1013L, -2.058903881920696086033171142046100185783e1017L, 2.173044241735786946064676598703393618281e1021L, -2.307746591425236218893160658331303115253e1025L, 2.465962312241418731528973526597433097256e1029L, -2.651278087802503406316742676403301581549e1033L, 2.868048395658440423778896607880692085708e1037L, -3.121561373094393453726645989392054731637e1041L, 3.418246710091027042099932753084126095820e1045L, -3.765936717592482928796920675282930034018e1049L, 4.174194967165213973474293718362757753877e1053L, -4.654731142471753017867105249805137855862e1057L, 5.221926310090434518253178454907900079787e1061L, -5.893500145664015254409680930288710794031e1065L, 6.691361332576333738130720616841706994101e1069L, -7.642695184575063524608775697714741180954e1073L, 8.781359617440634128952082759434723165820e1077L, -1.014968338800868135594698909567734048618e1082L, 1.180079105471061498849752479044520598414e1086L, -1.380162016721660241308046692646452732446e1090L, 1.623685158291375662775444238282343536948e1094L, -1.921404880943289359290531906131400049399e1098L, 2.287040419533950152851434188305457266969e1102L, -2.738162880206032093123060939173765335255e1106L, 3.297371307848643161532227459901386725801e1110L, -3.993854689967542662299211323085023297602e1114L, 4.865474805885735467044047308902313673643e1118L, -5.961554732739027308247618738765152679497e1122L, 7.346627151757492821447573639763873833441e1126L, -9.105493288459908620636712748727395637965e1130L, 1.135007867626164861991621396462821975167e1135L, -1.422876214067403769204874786137232627418e1139L, 1.793912271573925309173135913914667878908e1143L, -2.274542916104231188526120123855259514144e1147L, 2.900273688809987694128857655036783261991e1151L, -3.719022795563122339874875448447744493398e1155L, 4.795753420982845153626611023078973364321e1159L, -6.218937220186281310109009529226561379773e1163L, 8.109611247999584815668395828940708619394e1167L, -1.063412316303440216539797215354141158589e1172L, 1.402214363674117662460496032135704328989e1176L, -1.859223235464558752766840772026058694872e1180L, 2.478828203789903637835992128856742276028e1184L, -3.323169416193176673655321536761413885767e1188L, 4.479640207312477092938541546776915956580e1192L, -6.071721672924085739424644485636889518799e1196L, 8.274698015123579607850404326757887762270e1200L, -1.133855131459773018024052539697784205966e1205L, 1.562146222050424344025824344480153248984e1209L, -2.163904570724750459592352173471446831752e1213L, 3.013703210722669908901286635073603018696e1217L, -4.219903244242308803914269531001720703294e1221L, 5.940703220571043642186808904696174833998e1225L, -8.408147464216029127243257448169774333631e1229L, 1.196419999747411909144144315499654470715e1234L, -1.711518922741148710381740436694440587059e1238L, 2.461434539630850545757453894977350505251e1242L, -3.558748530932574002484841810677232366801e1246L, 5.172525606281917297657859608800373729529e1250L, -7.557850217376323621984784308774476917753e1254L, 1.110141075986004209769735296234549704181e1259L, -1.639216556732622481406083885926912451281e1263L, 2.433138328152562628385514545400044125983e1267L, -3.630476645219033020888837165221286413171e1271L, 5.445289518636306992942604775585977779418e1275L, -8.209806424989072060381590985042272020067e1279L, 1.244209849774134691374848390346442737613e1284L, -1.895384488692308848372754844910263931874e1288L, 2.902272596647764894203369746806169285113e1292L, -4.466944174025026625137032739317650862593e1296L, 6.910485739507636504313238347702354354916e1300L, -1.074550085668784170644854815272144687769e1305L, 1.679419258904938802199084915274175753529e1309L, -2.638155207645646220849795321076977230763e1313L, 4.165284786632654168563096850610185378233e1317L, -6.609774274649031371770290191295685774584e1321L, 1.054194100570841329575393359295845860860e1326L, -1.689822316104196916970708778265725885275e1330L, 2.722340957904912685605914893019783431164e1334L, -4.407776313964403233676810178851005163725e1338L, 7.172436210641903635864868181569129834361e1342L, -1.172947440100495955246356688225986736990e1347L, 1.927745674072824377954824961348211728006e1351L, -3.184013467435655962214317208087993711563e1355L, 5.285045125125832341263897233405196808096e1359L, -8.815883582819232027207118521581424783107e1363L, 1.477818368424505276711779171224799759099e1368L, -2.489482576496570159333357550363134602876e1372L, 4.214292881345076419678976329218843808204e1376L, -7.169068531615459070909644981451297906220e1380L, 1.225513133750594558180516896275774441895e1385L, -2.105160827387119480607950260289853896637e1389L, 3.633787605672960549893307203363402915249e1393L, -6.302830804027849515239463308430185990705e1397L, 1.098521433860299633481449685364914115468e1402L, -1.923858597401607622723144320370279518600e1406L, 3.385512828549942051667348582951554570164e1410L, -5.986286250836771248147827011780631183980e1414L, 1.063572794668186370728928272374836554300e1419L, -1.898666684876492795233907174493757572290e1423L, 3.405627002840442789235393111726609930533e1427L, -6.137724140284450036591063946055819333244e1431L, 1.111411024660941507986132154479364267486e1436L, -2.022060876221034821890406900217875915949e1440L, 3.696248025817144690840539132103538834108e1444L, -6.788448439024998306316860676030442691610e1448L, 1.252615233049059554031883468823648511657e1453L, -2.322190433141265975888955985950824418729e1457L, 4.325200102353909846882217732999001735342e1461L, -8.093531903011880118699218269369570178812e1465L, 1.521558881878323790120983450270946857209e1470L, -2.873780311010933807686415826253380907421e1474L, 5.452903697278823304173192839252276211670e1478L, -1.039457922537509500320638240809547113575e1483L, 1.990610112724715126895008793014214505760e1487L, -3.829667853173777076954453401761025071562e1491L, 7.401624504283011888971231756333356050310e1495L, -1.437075122764477911733220492562365990710e1500L, 2.802940275035867428066581228962104019228e1504L, -5.491938363067613321364335249495394164430e1508L, 1.080961960603953462180593404647115933651e1513L, -2.137290931892412298654741768897581319007e1517L, 4.245031321673807283498263276791307370788e1521L, -8.469499523038763989328773224520912663309e1525L, 1.697421812794203793865032206191322699261e1530L, -3.417217332563937242285349373774004020539e1534L, 6.910378594841763785923780822895851271770e1538L, -1.403696282437585785557998429691459557649e1543L, 2.864060533055333035232343601021192111053e1547L, -5.869818290384811353182423286543086530728e1551L, 1.208359745327224593486268988808338456906e1556L, -2.498576742140453770373914215325521001990e1560L, 5.189311407347546310078739863704346083861e1564L, -1.082537954843916294257278789980768336964e1569L, 2.268238255751421312559806122980932952706e1573L, -4.773557403917983369065731568732198697502e1577L, 1.009019097334998841920279535262007639746e1582L, -2.142181266523235177327239693359275472557e1586L, 4.567814904130855969979178320003286614868e1590L, -9.782550516204803195398428611221899469345e1594L, 2.104180123097086948576304557651398411373e1599L, -4.545658958087323864004652894518442709646e1603L, 9.862563944609427542603740078470901803131e1607L, -2.149105846582226970866569209122813809019e1612L, 4.703235567543888152049628411354542509156e1616L, -1.033719212601584878353206879472796545848e1621L, 2.281767401903848796732740825793310514456e1625L, -5.058236070813950229238666252351966279306e1629L, 1.126112519657857205642546937554224492775e1634L, -2.517766761987679577706779689880657777343e1638L, 5.653225190181653388317503182908983211029e1642L, -1.274735955461074142223278576503188429497e1647L, 2.886578974679460464298863945016671299242e1651L, -6.564203307141426181809363135003467581753e1655L, 1.499036144473064593308260681782048262301e1660L, -3.437714715599902386917108442954580869236e1664L, 7.916830957072777234152907034541325149479e1668L, -1.830850567422571420661248197094782575285e1673L, 4.251778280827419894527511469762091846660e1677L, -9.915182507286989818033146623995507108134e1681L, 2.321878208636697663781227497233334385222e1686L, -5.459879022461660582811365437190884471726e1690L, 1.289222044549922720398543474297554204559e1695L, -3.056819658344217799458557578658863826289e1699L, 7.277891759142725294172926258364455941365e1703L, -1.739928293433385104144012025546489673795e1708L, 4.176797408823713136137404972612780406904e1712L, -1.006788178307821554781930741698052910780e1717L, 2.436754569909644399766538111317379484511e1721L, -5.921896599028498715774458493117079340155e1725L, 1.445045688171565118619109316933316429671e1730L, -3.540547766876069233350621578795319652040e1734L, 8.710114552028472554054293344204504325978e1738L, -2.151484527880464463303897113553085899101e1743L, 5.335928195512405709733771642389502809087e1747L, -1.328726408335015910030370523083559660016e1752L, 3.322090527232917400247098823651437597786e1756L, -8.339387326241218096865362177688582376376e1760L, 2.101842203781264395369771906884644062395e1765L, -5.318704469415522036482913743767085545209e1769L, 1.351288005941730688647540059088127991581e1774L, -3.446853546858473171100748720136784228698e1778L, 8.827284762030783576089954173424852998700e1782L, -2.269642226090373319660782216907175419317e1787L, 5.858820683661708553422363777419430816755e1791L, -1.518385813684321665045387969920683656625e1796L, 3.950661327164595923092260035122668890334e1800L, -1.031976516347387969958181456058243183780e1805L, 2.706317892325103782207094286049104555552e1809L, -7.125140422584701175967252533378906957380e1813L, 1.883260203116768075569432925204868418472e1818L, -4.997193687108743666000994570700725873035e1822L, 1.331182722092654526185433799891693838871e1827L, -3.559930289076558484535632566755216035553e1831L, 9.557281027056970446117541983785660301558e1835L, -2.575805002229372523547972911961335317502e1840L, 6.969058431277067406841032797913179025984e1844L, -1.892842481279278678390672746902260183506e1849L, 5.160964211693777744707760614147460787285e1853L, -1.412602588198037643242529860614298968137e1858L, 3.881313379962387603749693387037174052146e1862L, -1.070542170988009009334148472388319844527e1867L, 2.964094312414144330805731101996829908435e1871L, -8.238350132106899955856124602934281976453e1875L, 2.298504171050560756192352106062598639825e1880L, -6.437303944649223478093890316531995121228e1884L, 1.809727811843121957353712606428292269805e1889L, -5.107047553992257935533518628886728031061e1893L, 1.446674478990385642488446075734631327506e1898L, -4.113513327511444762766719175770513771122e1902L, 1.174067517257431444028448391638451935667e1907L, -3.363630086409895071362533854123306097827e1911L, 9.672868956071838221096869293070568259792e1915L, -2.792101741911955365960369780457612630184e1920L, 8.089710604557382430162031502761771390568e1924L, -2.352650988877130983061761312962677887796e1929L, 6.867549079740051556501575104006222995568e1933L, -2.012161201632998475706904405535757516336e1938L, 5.917489529279588702317256137229398357271e1942L, -1.746718667239329545125902248821502764273e1947L, 5.175069416058975040990816515838893249437e1951L, -1.538913401594651457295303469904084052963e1956L, 4.593185746210984655636051293374195150815e1960L, -1.375981868450401919299150690829612124045e1965L, 4.137207965217520410530508053863759216958e1969L, -1.248518564582257710069294326648626362439e1974L, 3.781575291117895093413381897917341286951e1978L, -1.149575999691408110085856948595444100435e1983L, 3.507413095836612229403470531176947165451e1987L, -1.074032838410645352804690949680310176413e1992L, 3.300857202456564870338466973024760446263e1996L, -1.018149578840803516349758843017979498322e2001L, 3.151876950233613792531594490714752800621e2005L, -9.792574827376149360558532022944033224780e2009L, 3.053456145978161645823454710737904504036e2014L, -9.555442346102849014299990542596620094035e2018L, 3.001037449298122384017009412541525703002e2023L, -9.459120112371096268275049056229023773120e2027L, 2.992168042152196502453442556462819104060e2032L, -9.498922680869041470681858599915282791899e2036L, 3.026307717971075309746179763189393755074e2041L, -9.676079238806159594565350708123427510151e2045L, 3.104778286352798464772361361434013339088e2050L, -9.997786802782252742109475924344598057966e2054L, 3.230847952724856366943939804248186203776e2059L, -1.047769651900498931701604323213605884945e2064L, 3.409958102134053489747140426163802214042e2068L, -1.113687894644055086152064258459886518528e2073L, 3.650114509271160332136458711252217684956e2077L, -1.200536387553969483433239131469825141412e2082L, 3.962482337718333099498977337189304099484e2086L, -1.312441206957064803437100929905979391106e2091L, 4.362246723746013772563799740886664288515e2095L, -1.454975881895253548422481637083633839534e2100L, 4.869831412214692119172895822285084162147e2104L, -1.635618419512383251104125916207188960680e2109L, 5.512611314145041257838234038980389596534e2113L, -1.864392957231340288547618808749072127289e2118L, 6.327317613106621547060670091824665547127e2122L, -2.154772001506498703267302897994526372056e2127L, 7.363426139490286496267931634843475368903e2131L, -2.524950643808031915843604894357998905460e2136L, 8.687956390288096215918373666581638675156e2140L, -2.999656978200020459428228924242615592768e2145L, 1.039231328851609224822335039430898644149e2150L, -3.612742437616019936358910410005123924796e2154L, 1.260211309932738404790711574105022002093e2159L, -4.410916378453971105434385837025433805752e2163L, 1.549140617923265948720013792673729394719e2168L, -5.459173749226782924959103886664322964926e2172L, 1.930343307630952098252884031069043541182e2177L, -6.848749229218425353808144618581305978045e2181L, 2.438117138001365487681440577590059588102e2186L, -8.708873656769794358508423272379627581292e2190L, 3.121268068338199458891764932384819739714e2195L, -1.122430216307539309816165910733145404999e2200L, 4.049900779207199370582177687160985635615e2204L, -1.466167983141158219266077836130256565915e2209L, 5.325678718693772500250292767751070974887e2213L, -1.940955845102272053048140384364058448998e2218L, 7.097467198361219669927211698104447309186e2222L, -2.603968771680987683436428778397387110896e2227L, 9.585403285394812946713320044815117440444e2231L, -3.540176030547640510648455468270569908446e2236L, 1.311827683984025111744358347783996339730e2241L, -4.877124229155333857009747836542843294702e2245L, 1.819213075760490882591173222316749809951e2250L, -6.808221630329265915405178596748950929642e2254L, 2.556299969544109052724772800143396857058e2259L, -9.629763347675306704861859899230073979116e2263L, 3.639508580119285595844040783082958425575e2268L, -1.380037493555816309137481185927387732499e2273L, 5.249980712165216709135893538080020409581e2277L, -2.003737844109055078145975651407367170529e2282L, 7.672522280806944397358668566379646540213e2286L, -2.947454993639165318799389781921184991045e2291L, 1.135966912801707623489383623092951142963e2296L, -4.392293711194501621873299212059053651432e2300L, 1.703813210168560937608104155973968112409e2305L, -6.630636743874062041158387022015853902938e2309L, 2.588742636486379690203698247275411406029e2314L, -1.013959594068423546627946242481463893979e2319L, 3.984265821528043268586235974854766821078e2323L, -1.570614519682157047612769672066387881154e2328L, 6.211297381339606877062824459742129064477e2332L, -2.464246931985476159686671650962783785426e2337L, 9.807833742601662212615240518855757197483e2341L, -3.916036434571217691317276306031837539092e2346L, 1.568566392975837368624727722120313955274e2351L, -6.302885887601142677858008037129298948063e2355L, 2.540704455306077495480843691828334210014e2360L, -1.027412480318234348899627142408950111875e2365L, 4.167823618450297116765978030480648316769e2369L, -1.696076602731914277275203926124423530377e2374L, 6.923904505633301788461482786634220738504e2378L, -2.835463065742506394026733592206185459035e2383L, 1.164828772275756526225951620927486307632e2388L, -4.800242878545012539781545966693324656699e2392L, 1.984381759611877246529319121941597679107e2397L, -8.228979942542641498511023600269641046627e2401L, 3.423130231367101727862739208673375060101e2406L, -1.428418168129733054582191895023094524495e2411L, 5.979153801634459282232521647160044877770e2415L, -2.510581926948409809562349588087762800160e2420L, 1.057443785053915411991029410076722022815e2425L, -4.467723713549428749678277264414266162837e2429L, 1.893474116528533144079731251913008472748e2434L, -8.049601965052954947260081891142509464888e2438L, 3.432648527503971149009691133946275281368e2443L, -1.468324699963694393989960228042259134294e2448L,
+      //
+      // 1302-1600: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C1302%2C1600%2C2}]
+      6.300146502435743791500010801885493871234e2452L, -2.711520667146768856688291798851999580833e2457L, 1.170595555513900137297344452318266434006e2462L, -5.069095411973246242900074508988493530542e2466L, 2.201819284807954055092117706033113168896e2471L, -9.593088725189386197503123561368325167085e2475L, 4.192362385909155628936230811010649614060e2480L, -1.837725836941968309866675158105812946762e2485L, 8.080201101491972605313807752565294881374e2489L, -3.563536075527215702966392543784039539240e2494L, 1.576361051321107275181955665159661781175e2499L, -6.994292466180175594372663323941761853364e2503L, 3.112744353537336702834647901141392426258e2508L, -1.389481328370627358752727485697345194612e2513L, 6.221134636655213696041740685131223999953e2517L, -2.793779613656947577224654924852010601105e2522L, 1.258399062987759035354039924686781081603e2527L, -5.685208194704131918461885165870560583895e2531L, 2.576167857759537340210434756292816456179e2536L, -1.170846052338591953257169251219597581763e2541L, 5.337296787116189575571202979672747140313e2545L, -2.440264475369219459038748840841422948951e2550L, 1.119037151526195093932933161706501865175e2555L, -5.146858829220973887154576240993607686435e2559L, 2.374259791963193693837576781321391741634e2564L, -1.098501215269400934956638118646657823799e2569L, 5.097500369683616795005376807036889542869e2573L, -2.372446971688020647583535886090779018865e2578L, 1.107430282014636546248612381377039463753e2583L, -5.184597227131050012643138079903381280471e2587L, 2.434392040100910394476893838832599310265e2592L, -1.146412753331162872665743308094817095949e2597L, 5.414578104816988124950636101250217797539e2601L, -2.564835392810685332173156758121489913946e2606L, 1.218495070518549208066544111736985586178e2611L, -5.805713573821806672815019495319510297824e2615L, 2.774298194574319430697819781128985128618e2620L, -1.329580186505564627453485444017911980430e2625L, 6.390545858902318479863947547243743500916e2629L, -3.080502542499571035376377703435361520427e2634L, 1.489236104239976282318361008292980814533e2639L, -7.220413839991892382038608955317126799684e2643L, 3.510874916591640642524021216241607185085e2648L, -1.712070118580404599831061485055269100525e2653L, 8.372956919832386730490070625622785478703e2657L, -4.106629146981883685523102256292669054596e2662L, 2.019945438530802964718619732330776495740e2667L, -9.964133277392242111939720494354938982970e2671L, 4.929278642971447854669801547226335041410e2676L, -2.445509657169810919463982615395074704130e2681L, 1.216734421265677299127016883839223226884e2686L, -6.071008437677720186241562251151490713584e2690L, 3.037824949882992896564570441252792097027e2695L, -1.524402878612630565501569310883356490225e2700L, 7.671320530781999359200097739951316234193e2704L, -3.871436167706734376478728954716915204399e2709L, 1.959313530432202158587932399068682252335e2714L, -9.944063618400630821320953821427307024297e2718L, 5.061161998202463346818982228476199873781e2723L, -2.583219090831132705328958245740715185448e2728L, 1.322193991367293532684189527174543501836e2733L, -6.786569982732483290873213417465458376706e2737L, 3.493212334804776543395067018414547811062e2742L, -1.803090099978261928508495412750404640933e2747L, 9.333100843930216567894508007158644926767e2751L, -4.844499031405982604449146511179496492045e2756L, 2.521648090959971240812330574936006906830e2761L, -1.316227870932708474838173333385377250286e2766L, 6.889488826832738674261056521130795910494e2770L, -3.616184242864384509259984293501533623932e2775L, 1.903356124758119137116543283603627028779e2780L, -1.004601544584640657081847200643996069583e2785L, 5.317043885597842225603585588404817559596e2789L, -2.821938866752488868682751438901900485500e2794L, 1.501842023003449590337997900945924161741e2799L, -8.014908048137216649348740300633172710524e2803L, 4.289126235121619907138036129192558937445e2808L, -2.301619137231461344870820700320913118444e2813L, 1.238485136850053215006962645111854705210e2818L, -6.682503731149007943059244518074044280490e2822L, 3.615572393938012932030234169574978859655e2827L, -1.961565108627429629104703146282982075623e2832L, 1.067123259692924564435881096382837264046e2837L, -5.821179870182035246401397327057170726418e2841L, 3.184127229476322727732208017279268211356e2846L, -1.746429902183019597973436257300843998825e2851L, 9.604873565299766333876882842813498685054e2855L, -5.296759978724702692134960752308186890356e2860L, 2.928906353338652198977536576170287112391e2865L, -1.623961162577704769945821804737884742792e2870L, 9.028574047002736235613238355032484299017e2874L, -5.033087486357905828950503441308068892610e2879L, 2.813325650062267479031371852434194635210e2884L, -1.576791132296320840138263753339056345362e2889L, 8.861258343945925667272164531504265693289e2893L, -4.993236404321511029440212686547068244002e2898L, 2.821192993950901287717082243608730217471e2903L, -1.598254169674379493385730199445427966752e2908L, 9.078617590346932363947095804057608979359e2912L, -5.170742114456472142154347566092068443393e2917L, 2.952866185102528847516095880416675972086e2922L, -1.690794578626103552690094140317813413244e2927L, 9.707168799669516048238542260085175133847e2931L, -5.587884732306715493795271931175883605707e2936L, 3.225179489154957423492905957887744116530e2941L, -1.866424419669188178697802576490431604300e2946L, 1.082967626854618222657109354056973072044e2951L, -6.300392007169862865282706277272018077291e2955L, 3.675066377245428685118763485986517510658e2960L, -2.149348371085132073107516253339849053182e2965L, 1.260349351812619395000600434630904474324e2970L, -7.409963623771231302980906971935254993610e2974L, 4.367980758467862686643231700861155889684e2979L, -2.581566823350789671250829457603555544100e2984L, 1.529757357568342629912560827243282062227e2989L, -9.088595394263364554625061567617375176719e2993L, 5.413829169254585648363594604231030415354e2998L, -3.233288119606092759447005827969216281573e3003L, 1.936042437734875803183915765854038424658e3008L, -1.162289934202291715747729318797398221667e3013L, 6.995870350500567071550614251287615697508e3017L, -4.221776496490106417392945233048068288503e3022L, 2.554309239868912570382343877718991746122e3027L, -1.549440871550119801225143558087410562418e3032L, 9.423199525954784955533959981278992475051e3036L, -5.745689660772387668861183913170050552119e3041L, 3.512407521007240798565045328376471603253e3046L, -2.152708113797517364614914569890010876143e3051L, 1.322761289733739440340237168659770154654e3056L, -8.148777388506488753591136948542248584098e3060L, 5.032880858479326069741729004270784264612e3065L, -3.116396010103058126269735274818345780360e3070L, 1.934634831148214353514796782480703021435e3075L, -1.204077166243116651938489240924641810276e3080L, 7.513065583444964704795707060501161621868e3084L, -4.699873512563164914493150520500838535415e3089L, 2.947541197349762411713872934523813866703e3094L, -1.853262416286420077763886100673646141885e3099L, 1.168196427912100545575264493997591040800e3104L, -7.382362285873345348505276546404015842875e3108L, 4.677071041058096429847797962954927487730e3113L, -2.970642034084362431442183248944824506476e3118L, 1.891572688282564476274920103912259755482e3123L, -1.207509963440193713810418554061532113326e3128L, 7.727731208240101791845515599659441557781e3132L, -4.957988488048495669466804712012179891532e3137L, 3.188965862446236259925047956715566822864e3142L, -2.056286895821370106507670239256782411337e3147L, 1.329246918771714093479509313343886287414e3152L, -8.614188519577835653765633797787633659253e3156L,
+      //
+      // 1602-1900: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C1602%2C1900%2C2}]
+      5.596396533621874175909933615343145642161e3161L, -3.644908483469388437457938883454376864180e3166L, 2.379838409026860469990569665632800095988e3171L, -1.557720925267669865362152155022069166772e3176L, 1.022143420270029721682551084917730373739e3181L, -6.723767358891570842116651998814252095792e3185L, 4.433950491570308179905446963723780229747e3190L, -2.931196854668917448553150023532223509373e3195L, 1.942557068752664549549945921392100172355e3200L, -1.290553202978622786891265558106235068695e3205L, 8.595082329732118303768775883557789195136e3209L, -5.738453265222970049867280061719670658457e3214L, 3.840687915100689856736926915331157331684e3219L, -2.576862441955523551149886625900059307506e3224L, 1.733166107320377310388765047659987844208e3229L, -1.168569552450178559412843683052610870569e3234L, 7.898289836694980777809433306209459851871e3238L, -5.351485909164216694400535493924387979018e3243L, 3.634772439350395177931952925644409735777e3248L, -2.474801048002975145046569303233576339695e3253L, 1.689126939254790850063878942448569759390e3258L, -1.155691524500722774057997965355407962525e3263L, 7.926435404542361405718288670391575676323e3267L, -5.449654814183048796524718620178906854846e3272L, 3.755898589900254795894812942275711835138e3277L, -2.594843902682143854622514329649211211808e3282L, 1.797048752397789969347915328338360264536e3287L, -1.247551415074438712713815166107969504456e3292L, 8.681719521514448143910215886388510318746e3296L, -6.056203898213120922016159444227958572276e3301L, 4.234882876331814099029781995617143573641e3306L, -2.968432911643338866295929748049749932906e3311L, 2.085723508930484816454740610260790948864e3316L, -1.469023169879432026361623513301566735138e3321L, 1.037150346505052892302077637883522696572e3326L, -7.339977067836656769144838365069396168014e3330L, 5.206985412168234130596004552956337839140e3335L, -3.702673773319239583641029108403509825141e3340L, 2.639251227995760315076225206168354089692e3345L, -1.885736353072698581595150856674914203383e3350L, 1.350563292338261784288559687678302458996e3355L, -9.695749980998301526113046898985991802000e3359L, 6.977167462628398202151721319169989304520e3364L, -5.032768280399753942925624560483352299263e3369L, 3.638844963651800168080623511900705036698e3374L, -2.637228631269251606169613775399022890118e3379L, 1.915836351653767108720464847696767898597e3384L, -1.395064293615007319328267865803567670760e3389L, 1.018249052614943190644465556486933211307e3394L, -7.449662162606857550867922631658930320805e3398L, 5.463119632208085241594107781601567713991e3403L, -4.015736541676989144201935890497836963875e3408L, 2.958754190183866660901503059509579790900e3413L, -2.185096074054288399312733179064098492511e3418L, 1.617517444557020250864919655301189186103e3423L, -1.200170662015511746748935675940010250555e3428L, 8.925888349899029449015791684428724952411e3432L, -6.653851763691885517669938275618991145962e3437L, 4.971722031098457895973348076474071155918e3442L, -3.723500582577984967442020337848702786829e3447L, 2.795153783541721373364976034391375710110e3452L, -2.103141577212720698169118819883801186873e3457L, 1.586129575320959267959148073466004084241e3462L, -1.198988457279648730711646682156242973137e3467L, 9.084402368157025658430300252246526602197e3471L, -6.898927494435965163817354296023108913714e3476L, 5.251332286149361587885046891266325872375e3481L, -4.006442950956739933884502808470603581850e3486L, 3.063718202820270282280659950794978994604e3491L, -2.348215284130973783732145823834807395920e3496L, 1.803952490148087317330011096671019781340e3501L, -1.389022326803437345760911068933754707688e3506L, 1.071986115818329525986099441493200866389e3511L, -8.292085224650940719705699485423856363908e3515L, 6.428829064452939640541475198655560890344e3520L, -4.995654440302797445368056643032307686314e3525L, 3.890847042582299188849273838681034339406e3530L, -3.037288555751484681537442833929275697351e3535L, 2.376385803695694695338601696534348875191e3540L, -1.863527130251861900692886008704804849076e3545L, 1.464674913498036269270793715104706378182e3550L, -1.153804954579033578659954846698233083197e3555L, 9.109783835348935092264268296199541780964e3559L, -7.208869193983001804305451104827153729326e3564L, 5.717530734277611949162917337810749919265e3569L, -4.544970302634007326980094771330550661605e3574L, 3.621042850825283032134228901678636353355e3579L, -2.891447067949778492831490654980043715471e3584L, 2.314060419397710657435821461707043283167e3589L, -1.856140759923563235273220981623595304434e3594L, 1.492185412981476596273279338314204171587e3599L, -1.202290032627175365810126250991853594801e3604L, 9.708881154579770196658265042625239421053e3608L, -7.857809850747029705680072304049448493252e3613L, 6.373898598298513400228819113197728735438e3618L, -5.181780406472117449048907989647202286666e3623L, 4.222036621953044040518942750638183171221e3628L, -3.447728386429130175025813550845575613047e3633L, 2.821701521717856346224159586852612710800e3638L, -2.314488376711998526455043944505424906920e3643L, 1.902671298033180765286213227393060711096e3648L, -1.567603736821312488140289549008391847440e3653L, 1.294408945316538946551785312385509945367e3658L, -1.071194533081615830960091702262923009420e3663L, 8.884351908108581551151252566466606126397e3667L, -7.384866682828103669170236267589653324531e3672L, 6.152023838008155718180876735217718355563e3677L, -5.136304310431705506236573876510219357975e3682L, 4.297736808124296434723193397876220759378e3687L, -3.603994887745884762510172194982172483480e3692L, 3.028884745605031552399167746007361297342e3697L, -2.551141302205187365552982635794121855138e3702L, 2.153467982869535549299173317536193051608e3707L, -1.821769476343602094059466497311600827296e3712L, 1.544537580582347892980177956984101211006e3717L, -1.312358705945937257247030754517293537539e3722L, 1.117518229297781388884979995402355617235e3727L, -9.536820860779441793021624381677086661097e3731L, 8.156400668831968026931547065507466530546e3736L, -6.990984948728184142718575396052260691181e3741L, 6.005124901126818071638224144541102727563e3746L, -5.169500241880947716732682089328427995109e3751L, 4.459815478235310026240134567325749844182e3756L, -3.855902253361684187081283218890336962427e3761L, 3.340988024176995223515640815937037040546e3766L, -2.901099226680215736735094376078800376829e3771L, 2.524573363444334459448089563912567842927e3776L, -2.201659455716348555524529213295341212492e3781L, 1.924190302190936448078364755844591374353e3786L, -1.685313186099770223843319514432495898517e3791L, 1.479268235966730475749985741048766689808e3796L, -1.301205702893883803117530921635013780575e3801L, 1.147035071153450453405384269242743907426e3806L, -1.013300250456366849150496776951686112298e3811L, 8.970761720605591762300958007557533865346e3815L, -7.958829781488943084496783248922217392838e3820L, 7.076146954685024795720193943027902028642e3825L, -6.304798526260409199660290516451546966159e3830L, 5.629519616664188107056583939722984509867e3835L, -5.037281594099054092767959480843344929292e3840L, 4.516946091316834843581919268794683123349e3845L, -4.058975118925834202620358386772092359951e3850L, 3.655187798978978909014603682039470653549e3855L, -3.298555903041546671060101785513812175322e3860L, 2.983031738662727912016882399515879119620e3865L, -2.703403043317732979516341931451317866898e3870L, 2.455170460800096241793872443768546335444e3875L, -2.234443928432490538417605502448376856290e3880L, 2.037854924078003280537856980560782325730e3885L, -1.862482033918775734840779765743099458137e3890L,
+      //
+      // 1902-2200: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C1902%2C2200%2C2}]
+      1.705787724951999960095629912416210969679e3895L, -1.565564556110550991891247404758895970376e3900L, 1.439889351869832939488618785632174464789e3905L, -1.327084102784257406218693901793045990520e3910L, 1.225682557296027075027021534960026145706e3915L, -1.134401635488994148555787301654561211982e3920L, 1.052116934052356802920509999705307165985e3925L, -9.778417073593082219082361206542342793584e3929L, 9.107088061888562704837019028349522303725e3934L, -8.499551364633102138471246155980056936129e3939L, 7.949082681085658044610890152056533167407e3944L, -7.449748809722797718736397140511396011691e3949L, 6.996307824769340144608141799981589288378e3954L, -6.584122718472954006131003060359621706243e3959L, 6.209086595833487707192492087176843233407e3964L, -5.867557793863165391821489909125720982339e3969L, 5.556303538475260373917478405626416604297e3974L, -5.272450955936249442242634142613834212778e3979L, 5.013444428433789818228792126117223030641e3984L, -4.777008429684552423800736200488532033034e3989L, 4.561115100786341787876705283291018781137e3994L, -4.363955932181992701667719449097126840439e3999L, 4.183917007557000586305945495258591147615e4004L, -4.019557342177353010692923286760895584096e4009L, 3.869589913635745758786275231296652917580e4014L, -3.732865038934070181861017140563175000872e4019L, 3.608355799736107390800162778737339576843e4024L, -3.495145258697474565347261083975193776541e4029L, 3.392415245050326563747729613872524362741e4034L, -3.299436517958948801426629481782413630714e4039L, 3.215560142306355508598119430378551642857e4044L, -3.140209934146377815556058799557727461298e4049L, 3.072875852591406752692761744649563131272e4054L, -3.013108231854799187724018548255922550991e4059L, 2.960512761914376268185064129600549308882e4064L, -2.914746139139036596123006476633770383901e4069L, 2.875512319506974985103149834921665445532e4074L, -2.842559316984704569380036093537576068104e4079L, 2.815676498441436148701483904115879856704e4084L, -2.794692334326268275058539147656334465534e4089L, 2.779472571396106785963004020814493340829e4094L, -2.769918800191406321625251621260024635680e4099L, 2.765967395840433013288935879837390099329e4104L, -2.767588816244119880300161388073836623878e4109L, 2.774787246856347651152278076466043136230e4114L, -2.787600586224957950622601135620189837948e4119L, 2.806100771288225169339048358106052817280e4124L, -2.830394446218080573456394167711739786431e4129L, 2.860623983452244712039094143642843717029e4134L, -2.896968870550611723525738907034588104300e4139L, 2.939647481737606306044335918078617963078e4144L, -2.988919258547518526076380181812161398808e4149L, 3.045087329976721023952450383837883029431e4154L, -3.108501609077197464748958150625867523408e4159L, 3.179562410123820875787052833975010965963e4164L, -3.258724638491880104953913719767939138170e4169L, 3.346502614347964869115073881474258766546e4174L, -3.443475601364631413158991572423086599816e4179L, 3.550294123121350747300886840907918182129e4184L, -3.667687162886053419715985091863398517145e4189L, 3.796470357354794420044278000297864085607e4194L, -3.937555311976846882455930574021795626971e4199L, 4.091960185075595842547638450930710467324e4204L, -4.260821710519620959138720129506770036460e4209L, 4.445408854703156440576808070360934740837e4214L, -4.647138333645908068599900650548418672065e4219L, 4.867592250805288922190809906525766574205e4224L, -5.108538156515551259475573296900660666192e4229L, 5.371951876776035157276013631113314852508e4234L, -5.660043513521220243900043448456234873940e4239L, 5.975287081834808618140945840817834710330e4244L, -6.320454323372684034118816565375206053746e4249L, 6.698653321371992324876559665938996023646e4254L, -7.113372643219128807424340495235606473967e4259L, 7.568531854202750881338746432078817214052e4264L, -8.068539383842553693076672384509126681464e4269L, 8.618358887685935324188596304168259394311e4274L, -9.223585437012291673660319256730398171887e4279L, 9.890533091606747031464718533600572123091e4284L, -1.062633567277107015128545384570274268438e4290L, 1.143906286231591191271274413511275981288e4295L, -1.233785411712565904499340744089870916842e4300L, 1.333307331840530219050170916015276125870e4305L, -1.443648758235403286296065629219598769529e4310L, 1.566147425967471851736562867318748510088e4315L, -1.702326086290842780634120184324081017286e4320L, 1.853920350455786350409148418966087344063e4325L, -2.022911043115598592197907512410632615740e4330L, 2.211561842992792253055716743938240466613e4335L, -2.422463130294011318178080247305407476096e4340L, 2.658583129381772791030436640519847627789e4345L, -2.923327636881988941081365085520742216540e4350L, 3.220609866329557159104267531058019683271e4355L, -3.554932228621330128152149026066400241546e4360L, 3.931482212643167323798366327390058684499e4365L, -4.356244944221399578650235478583297389113e4370L, 4.836135498303121165971331625888490168138e4375L, -5.379154636371461359750682662639062606297e4380L, 5.994572359716861309678596804350346692501e4385L, -6.693144535124290060793936095397161934045e4390L, 7.487368894313509797084395689517008597061e4395L, -8.391787970609807810531578161564037339793e4400L, 9.423348062978921203475110312003096820035e4405L, -1.060182516651648405903017734022504884319e4411L, 1.195033105063952979885086754342706651656e4416L, -1.349591538868673992167798923586925758429e4421L, 1.527028315253291113905307092657539132480e4426L, -1.731065051510920640409442255224015234974e4431L, 1.966076741510092840076264635935585216200e4436L, -2.237214093245750681191361238831105906202e4441L, 2.550550094903891445719729187215253324232e4446L, -2.913255853313667303707651906277658164129e4451L, 3.333811847072394764285817140850092324169e4456L, -3.822262084288044913490118858492563410392e4461L, 4.390520310533864198186202368026630430120e4466L, -5.052739449335052080092114976206610871466e4471L, 5.825757966350870043117899492954521458799e4476L, -6.729639942938203582008846884575881320532e4481L, 7.788329466816396015493306357116312471970e4486L, -9.030444674469025073047417528762134025409e4491L, 1.049024263381993629167658236142000524752e4497L, -1.220879351508964912255081664072251573277e4502L, 1.423541151220109512749655991050110438471e4507L, -1.662940118618541616964708044356967429362e4512L, 1.946219185900482116137855064775635250366e4517L, -2.281995008842006909631764011781911322493e4522L, 2.680678198213108543648324254258111216040e4527L, -3.154866427472784086389609599207759103500e4532L, 3.719827710160801797530420206201570269720e4537L, -4.394095404360277919140027580071549980218e4542L, 5.200201854779615608741690339830306148442e4547L, -6.165584312943608652377791415603277251516e4552L, 7.323705248531382981433751104158852636445e4557L, -8.715439846124090647163930834760361817820e4562L, 1.039079696609215651011736087603304766850e4568L, -1.241105689556982425619608247473478857800e4573L, 1.485143079696380339521658550262280772546e4578L, -1.780437412164973637340821168154300094802e4583L, 2.138372099157518882088209435171770222745e4588L, -2.572985071149069551034276570909360759588e4593L, 3.101615379617643734762997559011097203354e4598L, -3.745713657616368229906151946770042703357e4603L, 4.531859496161940719835150033082561700677e4608L, -5.493040495326927998321538336584233566465e4613L, 6.670262730603009306595018122252730741798e4618L, -8.114581584793494903775255213273982440688e4623L, 9.889666561810883044159054730371102725871e4628L, -1.207504541653929734716275932570097623330e4634L, 1.477021377885843688233899471354959308782e4639L, -1.809984912147908767583043524070645821179e4644L,
+      //
+      // 2202-2320: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C2202%2C2320%2C2}]
+      2.222043594325228980916360265527780300093e4649L, -2.732869701246338361699515268224049951411e4654L, 3.367233945421922463553518272642397177145e4659L, -4.156377225041273602431272489314020150392e4664L, 5.139764368092890466235162431795350591151e4669L, -6.367329693760865476879589228002216011370e4674L, 7.902356742934106007362514378717026407839e4679L, -9.825176966314431712897976595483070301406e4684L, 1.223792760178593282435724837135946867088e4690L, -1.527068151452750404853140815207477555192e4695L, 1.908935682572268829496101580401263597905e4700L, -2.390593888616966248780378941331847473699e4705L, 2.999171106576893833644521002894489856321e4710L, -3.769440655453736670024798444784356437578e4715L, 4.746047769851891438576002047529258107351e4720L, -5.986405469241447720766576164546767533359e4725L, 7.564466155536872051712519119999711534616e4730L, -9.575641408047918720040356745796976488951e4735L, 1.214322951835035451699619713803395497423e4741L, -1.542682591979864353012093794301924196234e4746L, 1.963334539793192183270983986567556358603e4751L, -2.503148969013901182572118121398034622584e4756L, 3.197076711250102964526567664729089847162e4761L, -4.090653552025822488578293526174572934858e4766L, 5.243302769651520536759521264615159906699e4771L, -6.732697170903775309261288127044088674182e4776L, 8.660529543801770516930589210020128142543e4781L, -1.116015823611149634592870112730519454113e4787L, 1.440675306432920129218036927923030695520e4792L, -1.863078034853256227415397798026969938881e4797L, 2.413595413458810442409656314019115041699e4802L, -3.132317029597258599678590012779717945144e4807L, 4.072246763371584312534474102756137619716e4812L, -5.303577511521827157146305369181950467569e4817L, 6.919417518688636032335131253584331645491e4822L, -9.043473312934241153732087612484569398979e4827L, 1.184037400265044213826044590639924237359e4833L, -1.552956685415800894409743993367334099777e4838L, 2.040404893052952221581694807126473204625e4843L, -2.685565763841580219033402331219206776210e4848L, 3.540927057361929050327811875290025248120e4853L, -4.676912607538885419407656762767991163574e4858L, 6.188165903566760647569323704623433330229e4863L, -8.202087471895029964699042637255411806373e4868L, 1.089045274355389654614196651761310970580e4874L, -1.448524684976553869119447042300206226148e4879L, 1.930028100376784839502387280956424581974e4884L, -2.576074799096023589462128312524664980682e4889L, 3.444369635011990347297134928452972402038e4894L, -4.613354441299253694113609154769978684993e4899L, 6.189834306866879018555349507257537840922e4904L, -8.319470760665157534580593571258276368233e4909L, 1.120124240070996761986102680587384813245e4915L, -1.510740451399746828351090108638980398124e4920L, 2.041108231091323198877509959371257503819e4925L, -2.762447751447012472733302936575873838539e4930L,
+#endif
+   }};
+
+   return bernoulli_data[n];
+}
+
+template <class T>
+inline T unchecked_bernoulli_imp(std::size_t n, const boost::integral_constant<int, 4>& )
+{
+   //
+   // Special case added for multiprecision types that have no conversion from long long,
+   // there are very few such types, but mpfr_class is one.
+   //
+   static const boost::array<boost::int32_t, 1 + max_bernoulli_b2n<T>::value> numerators =
+   {{
+      boost::int32_t(            +1LL),
+      boost::int32_t(            +1LL),
+      boost::int32_t(            -1LL),
+      boost::int32_t(            +1LL),
+      boost::int32_t(            -1LL),
+      boost::int32_t(            +5LL),
+      boost::int32_t(          -691LL),
+      boost::int32_t(            +7LL),
+      boost::int32_t(         -3617LL),
+      boost::int32_t(        +43867LL),
+      boost::int32_t(       -174611LL),
+      boost::int32_t(       +854513LL),
+   }};
+
+   static const boost::array<boost::int32_t, 1 + max_bernoulli_b2n<T>::value> denominators =
+   {{
+      boost::int32_t(      1LL),
+      boost::int32_t(      6LL),
+      boost::int32_t(     30LL),
+      boost::int32_t(     42LL),
+      boost::int32_t(     30LL),
+      boost::int32_t(     66LL),
+      boost::int32_t(   2730LL),
+      boost::int32_t(      6LL),
+      boost::int32_t(    510LL),
+      boost::int32_t(    798LL),
+      boost::int32_t(    330LL),
+      boost::int32_t(    138LL),
+   }};
+   return T(numerators[n]) / T(denominators[n]);
+}
+
+} // namespace detail
+
+template<class T>
+inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_b2n(const std::size_t n)
+{
+   typedef boost::integral_constant<int, detail::bernoulli_imp_variant<T>::value> tag_type;
+
+   return detail::unchecked_bernoulli_imp<T>(n, tag_type());
+}
+
+}} // namespaces
+
+#endif // BOOST_MATH_UNCHECKED_BERNOULLI_HPP
diff --git a/ThirdParty/boost/math/special_functions/detail/unchecked_factorial.hpp b/ThirdParty/boost/math/special_functions/detail/unchecked_factorial.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..09e3ee5eb2a36f930ee55c5f970111b0c26867f0
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/detail/unchecked_factorial.hpp
@@ -0,0 +1,856 @@
+//  Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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_SP_UC_FACTORIALS_HPP
+#define BOOST_MATH_SP_UC_FACTORIALS_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#ifdef BOOST_MSVC
+#pragma warning(push) // Temporary until lexical cast fixed.
+#pragma warning(disable: 4127 4701)
+#endif
+#ifndef BOOST_MATH_NO_LEXICAL_CAST
+#include <boost/lexical_cast.hpp>
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+#include <cmath>
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/tools/cxx03_warn.hpp>
+
+#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
+#include <array>
+#else
+#include <boost/array.hpp>
+#endif
+
+#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128)
+//
+// This is the only way we can avoid
+// warning: non-standard suffix on floating constant [-Wpedantic]
+// when building with -Wall -pedantic.  Neither __extension__
+// nor #pragma diagnostic ignored work :(
+//
+#pragma GCC system_header
+#endif
+
+namespace boost { namespace math
+{
+// Forward declarations:
+template <class T>
+struct max_factorial;
+
+// Definitions:
+template <>
+inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION float unchecked_factorial<float>(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(float))
+{
+#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
+   constexpr std::array<float, 35> factorials = { {
+#else
+   static const boost::array<float, 35> factorials = {{
+#endif
+      1.0F,
+      1.0F,
+      2.0F,
+      6.0F,
+      24.0F,
+      120.0F,
+      720.0F,
+      5040.0F,
+      40320.0F,
+      362880.0F,
+      3628800.0F,
+      39916800.0F,
+      479001600.0F,
+      6227020800.0F,
+      87178291200.0F,
+      1307674368000.0F,
+      20922789888000.0F,
+      355687428096000.0F,
+      6402373705728000.0F,
+      121645100408832000.0F,
+      0.243290200817664e19F,
+      0.5109094217170944e20F,
+      0.112400072777760768e22F,
+      0.2585201673888497664e23F,
+      0.62044840173323943936e24F,
+      0.15511210043330985984e26F,
+      0.403291461126605635584e27F,
+      0.10888869450418352160768e29F,
+      0.304888344611713860501504e30F,
+      0.8841761993739701954543616e31F,
+      0.26525285981219105863630848e33F,
+      0.822283865417792281772556288e34F,
+      0.26313083693369353016721801216e36F,
+      0.868331761881188649551819440128e37F,
+      0.29523279903960414084761860964352e39F,
+   }};
+
+   return factorials[i];
+}
+
+template <>
+struct max_factorial<float>
+{
+   BOOST_STATIC_CONSTANT(unsigned, value = 34);
+};
+
+
+template <>
+inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION long double unchecked_factorial<long double>(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(long double))
+{
+#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
+   constexpr std::array<long double, 171> factorials = { {
+#else
+   static const boost::array<long double, 171> factorials = {{
+#endif
+      1L,
+      1L,
+      2L,
+      6L,
+      24L,
+      120L,
+      720L,
+      5040L,
+      40320L,
+      362880.0L,
+      3628800.0L,
+      39916800.0L,
+      479001600.0L,
+      6227020800.0L,
+      87178291200.0L,
+      1307674368000.0L,
+      20922789888000.0L,
+      355687428096000.0L,
+      6402373705728000.0L,
+      121645100408832000.0L,
+      0.243290200817664e19L,
+      0.5109094217170944e20L,
+      0.112400072777760768e22L,
+      0.2585201673888497664e23L,
+      0.62044840173323943936e24L,
+      0.15511210043330985984e26L,
+      0.403291461126605635584e27L,
+      0.10888869450418352160768e29L,
+      0.304888344611713860501504e30L,
+      0.8841761993739701954543616e31L,
+      0.26525285981219105863630848e33L,
+      0.822283865417792281772556288e34L,
+      0.26313083693369353016721801216e36L,
+      0.868331761881188649551819440128e37L,
+      0.29523279903960414084761860964352e39L,
+      0.103331479663861449296666513375232e41L,
+      0.3719933267899012174679994481508352e42L,
+      0.137637530912263450463159795815809024e44L,
+      0.5230226174666011117600072241000742912e45L,
+      0.203978820811974433586402817399028973568e47L,
+      0.815915283247897734345611269596115894272e48L,
+      0.3345252661316380710817006205344075166515e50L,
+      0.1405006117752879898543142606244511569936e52L,
+      0.6041526306337383563735513206851399750726e53L,
+      0.265827157478844876804362581101461589032e55L,
+      0.1196222208654801945619631614956577150644e57L,
+      0.5502622159812088949850305428800254892962e58L,
+      0.2586232415111681806429643551536119799692e60L,
+      0.1241391559253607267086228904737337503852e62L,
+      0.6082818640342675608722521633212953768876e63L,
+      0.3041409320171337804361260816606476884438e65L,
+      0.1551118753287382280224243016469303211063e67L,
+      0.8065817517094387857166063685640376697529e68L,
+      0.427488328406002556429801375338939964969e70L,
+      0.2308436973392413804720927426830275810833e72L,
+      0.1269640335365827592596510084756651695958e74L,
+      0.7109985878048634518540456474637249497365e75L,
+      0.4052691950487721675568060190543232213498e77L,
+      0.2350561331282878571829474910515074683829e79L,
+      0.1386831185456898357379390197203894063459e81L,
+      0.8320987112741390144276341183223364380754e82L,
+      0.507580213877224798800856812176625227226e84L,
+      0.3146997326038793752565312235495076408801e86L,
+      0.1982608315404440064116146708361898137545e88L,
+      0.1268869321858841641034333893351614808029e90L,
+      0.8247650592082470666723170306785496252186e91L,
+      0.5443449390774430640037292402478427526443e93L,
+      0.3647111091818868528824985909660546442717e95L,
+      0.2480035542436830599600990418569171581047e97L,
+      0.1711224524281413113724683388812728390923e99L,
+      0.1197857166996989179607278372168909873646e101L,
+      0.8504785885678623175211676442399260102886e102L,
+      0.6123445837688608686152407038527467274078e104L,
+      0.4470115461512684340891257138125051110077e106L,
+      0.3307885441519386412259530282212537821457e108L,
+      0.2480914081139539809194647711659403366093e110L,
+      0.188549470166605025498793226086114655823e112L,
+      0.1451830920282858696340707840863082849837e114L,
+      0.1132428117820629783145752115873204622873e116L,
+      0.8946182130782975286851441715398316520698e117L,
+      0.7156945704626380229481153372318653216558e119L,
+      0.5797126020747367985879734231578109105412e121L,
+      0.4753643337012841748421382069894049466438e123L,
+      0.3945523969720658651189747118012061057144e125L,
+      0.3314240134565353266999387579130131288001e127L,
+      0.2817104114380550276949479442260611594801e129L,
+      0.2422709538367273238176552320344125971528e131L,
+      0.210775729837952771721360051869938959523e133L,
+      0.1854826422573984391147968456455462843802e135L,
+      0.1650795516090846108121691926245361930984e137L,
+      0.1485715964481761497309522733620825737886e139L,
+      0.1352001527678402962551665687594951421476e141L,
+      0.1243841405464130725547532432587355307758e143L,
+      0.1156772507081641574759205162306240436215e145L,
+      0.1087366156656743080273652852567866010042e147L,
+      0.103299784882390592625997020993947270954e149L,
+      0.9916779348709496892095714015418938011582e150L,
+      0.9619275968248211985332842594956369871234e152L,
+      0.942689044888324774562618574305724247381e154L,
+      0.9332621544394415268169923885626670049072e156L,
+      0.9332621544394415268169923885626670049072e158L,
+      0.9425947759838359420851623124482936749562e160L,
+      0.9614466715035126609268655586972595484554e162L,
+      0.990290071648618040754671525458177334909e164L,
+      0.1029901674514562762384858386476504428305e167L,
+      0.1081396758240290900504101305800329649721e169L,
+      0.1146280563734708354534347384148349428704e171L,
+      0.1226520203196137939351751701038733888713e173L,
+      0.132464181945182897449989183712183259981e175L,
+      0.1443859583202493582204882102462797533793e177L,
+      0.1588245541522742940425370312709077287172e179L,
+      0.1762952551090244663872161047107075788761e181L,
+      0.1974506857221074023536820372759924883413e183L,
+      0.2231192748659813646596607021218715118256e185L,
+      0.2543559733472187557120132004189335234812e187L,
+      0.2925093693493015690688151804817735520034e189L,
+      0.339310868445189820119825609358857320324e191L,
+      0.396993716080872089540195962949863064779e193L,
+      0.4684525849754290656574312362808384164393e195L,
+      0.5574585761207605881323431711741977155627e197L,
+      0.6689502913449127057588118054090372586753e199L,
+      0.8094298525273443739681622845449350829971e201L,
+      0.9875044200833601362411579871448208012564e203L,
+      0.1214630436702532967576624324188129585545e206L,
+      0.1506141741511140879795014161993280686076e208L,
+      0.1882677176888926099743767702491600857595e210L,
+      0.237217324288004688567714730513941708057e212L,
+      0.3012660018457659544809977077527059692324e214L,
+      0.3856204823625804217356770659234636406175e216L,
+      0.4974504222477287440390234150412680963966e218L,
+      0.6466855489220473672507304395536485253155e220L,
+      0.8471580690878820510984568758152795681634e222L,
+      0.1118248651196004307449963076076169029976e225L,
+      0.1487270706090685728908450891181304809868e227L,
+      0.1992942746161518876737324194182948445223e229L,
+      0.269047270731805048359538766214698040105e231L,
+      0.3659042881952548657689727220519893345429e233L,
+      0.5012888748274991661034926292112253883237e235L,
+      0.6917786472619488492228198283114910358867e237L,
+      0.9615723196941089004197195613529725398826e239L,
+      0.1346201247571752460587607385894161555836e242L,
+      0.1898143759076170969428526414110767793728e244L,
+      0.2695364137888162776588507508037290267094e246L,
+      0.3854370717180072770521565736493325081944e248L,
+      0.5550293832739304789551054660550388118e250L,
+      0.80479260574719919448490292577980627711e252L,
+      0.1174997204390910823947958271638517164581e255L,
+      0.1727245890454638911203498659308620231933e257L,
+      0.2556323917872865588581178015776757943262e259L,
+      0.380892263763056972698595524350736933546e261L,
+      0.571338395644585459047893286526105400319e263L,
+      0.8627209774233240431623188626544191544816e265L,
+      0.1311335885683452545606724671234717114812e268L,
+      0.2006343905095682394778288746989117185662e270L,
+      0.308976961384735088795856467036324046592e272L,
+      0.4789142901463393876335775239063022722176e274L,
+      0.7471062926282894447083809372938315446595e276L,
+      0.1172956879426414428192158071551315525115e279L,
+      0.1853271869493734796543609753051078529682e281L,
+      0.2946702272495038326504339507351214862195e283L,
+      0.4714723635992061322406943211761943779512e285L,
+      0.7590705053947218729075178570936729485014e287L,
+      0.1229694218739449434110178928491750176572e290L,
+      0.2004401576545302577599591653441552787813e292L,
+      0.3287218585534296227263330311644146572013e294L,
+      0.5423910666131588774984495014212841843822e296L,
+      0.9003691705778437366474261723593317460744e298L,
+      0.1503616514864999040201201707840084015944e301L,
+      0.2526075744973198387538018869171341146786e303L,
+      0.4269068009004705274939251888899566538069e305L,
+      0.7257415615307998967396728211129263114717e307L,
+   }};
+
+   return factorials[i];
+}
+
+template <>
+struct max_factorial<long double>
+{
+   BOOST_STATIC_CONSTANT(unsigned, value = 170);
+};
+
+#ifdef BOOST_MATH_USE_FLOAT128
+
+template <>
+inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION BOOST_MATH_FLOAT128_TYPE unchecked_factorial<BOOST_MATH_FLOAT128_TYPE>(unsigned i)
+{
+#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
+   constexpr std::array<BOOST_MATH_FLOAT128_TYPE, 171> factorials = { {
+#else
+   static const boost::array<BOOST_MATH_FLOAT128_TYPE, 171> factorials = { {
+#endif
+      1,
+      1,
+      2,
+      6,
+      24,
+      120,
+      720,
+      5040,
+      40320,
+      362880.0Q,
+      3628800.0Q,
+      39916800.0Q,
+      479001600.0Q,
+      6227020800.0Q,
+      87178291200.0Q,
+      1307674368000.0Q,
+      20922789888000.0Q,
+      355687428096000.0Q,
+      6402373705728000.0Q,
+      121645100408832000.0Q,
+      0.243290200817664e19Q,
+      0.5109094217170944e20Q,
+      0.112400072777760768e22Q,
+      0.2585201673888497664e23Q,
+      0.62044840173323943936e24Q,
+      0.15511210043330985984e26Q,
+      0.403291461126605635584e27Q,
+      0.10888869450418352160768e29Q,
+      0.304888344611713860501504e30Q,
+      0.8841761993739701954543616e31Q,
+      0.26525285981219105863630848e33Q,
+      0.822283865417792281772556288e34Q,
+      0.26313083693369353016721801216e36Q,
+      0.868331761881188649551819440128e37Q,
+      0.29523279903960414084761860964352e39Q,
+      0.103331479663861449296666513375232e41Q,
+      0.3719933267899012174679994481508352e42Q,
+      0.137637530912263450463159795815809024e44Q,
+      0.5230226174666011117600072241000742912e45Q,
+      0.203978820811974433586402817399028973568e47Q,
+      0.815915283247897734345611269596115894272e48Q,
+      0.3345252661316380710817006205344075166515e50Q,
+      0.1405006117752879898543142606244511569936e52Q,
+      0.6041526306337383563735513206851399750726e53Q,
+      0.265827157478844876804362581101461589032e55Q,
+      0.1196222208654801945619631614956577150644e57Q,
+      0.5502622159812088949850305428800254892962e58Q,
+      0.2586232415111681806429643551536119799692e60Q,
+      0.1241391559253607267086228904737337503852e62Q,
+      0.6082818640342675608722521633212953768876e63Q,
+      0.3041409320171337804361260816606476884438e65Q,
+      0.1551118753287382280224243016469303211063e67Q,
+      0.8065817517094387857166063685640376697529e68Q,
+      0.427488328406002556429801375338939964969e70Q,
+      0.2308436973392413804720927426830275810833e72Q,
+      0.1269640335365827592596510084756651695958e74Q,
+      0.7109985878048634518540456474637249497365e75Q,
+      0.4052691950487721675568060190543232213498e77Q,
+      0.2350561331282878571829474910515074683829e79Q,
+      0.1386831185456898357379390197203894063459e81Q,
+      0.8320987112741390144276341183223364380754e82Q,
+      0.507580213877224798800856812176625227226e84Q,
+      0.3146997326038793752565312235495076408801e86Q,
+      0.1982608315404440064116146708361898137545e88Q,
+      0.1268869321858841641034333893351614808029e90Q,
+      0.8247650592082470666723170306785496252186e91Q,
+      0.5443449390774430640037292402478427526443e93Q,
+      0.3647111091818868528824985909660546442717e95Q,
+      0.2480035542436830599600990418569171581047e97Q,
+      0.1711224524281413113724683388812728390923e99Q,
+      0.1197857166996989179607278372168909873646e101Q,
+      0.8504785885678623175211676442399260102886e102Q,
+      0.6123445837688608686152407038527467274078e104Q,
+      0.4470115461512684340891257138125051110077e106Q,
+      0.3307885441519386412259530282212537821457e108Q,
+      0.2480914081139539809194647711659403366093e110Q,
+      0.188549470166605025498793226086114655823e112Q,
+      0.1451830920282858696340707840863082849837e114Q,
+      0.1132428117820629783145752115873204622873e116Q,
+      0.8946182130782975286851441715398316520698e117Q,
+      0.7156945704626380229481153372318653216558e119Q,
+      0.5797126020747367985879734231578109105412e121Q,
+      0.4753643337012841748421382069894049466438e123Q,
+      0.3945523969720658651189747118012061057144e125Q,
+      0.3314240134565353266999387579130131288001e127Q,
+      0.2817104114380550276949479442260611594801e129Q,
+      0.2422709538367273238176552320344125971528e131Q,
+      0.210775729837952771721360051869938959523e133Q,
+      0.1854826422573984391147968456455462843802e135Q,
+      0.1650795516090846108121691926245361930984e137Q,
+      0.1485715964481761497309522733620825737886e139Q,
+      0.1352001527678402962551665687594951421476e141Q,
+      0.1243841405464130725547532432587355307758e143Q,
+      0.1156772507081641574759205162306240436215e145Q,
+      0.1087366156656743080273652852567866010042e147Q,
+      0.103299784882390592625997020993947270954e149Q,
+      0.9916779348709496892095714015418938011582e150Q,
+      0.9619275968248211985332842594956369871234e152Q,
+      0.942689044888324774562618574305724247381e154Q,
+      0.9332621544394415268169923885626670049072e156Q,
+      0.9332621544394415268169923885626670049072e158Q,
+      0.9425947759838359420851623124482936749562e160Q,
+      0.9614466715035126609268655586972595484554e162Q,
+      0.990290071648618040754671525458177334909e164Q,
+      0.1029901674514562762384858386476504428305e167Q,
+      0.1081396758240290900504101305800329649721e169Q,
+      0.1146280563734708354534347384148349428704e171Q,
+      0.1226520203196137939351751701038733888713e173Q,
+      0.132464181945182897449989183712183259981e175Q,
+      0.1443859583202493582204882102462797533793e177Q,
+      0.1588245541522742940425370312709077287172e179Q,
+      0.1762952551090244663872161047107075788761e181Q,
+      0.1974506857221074023536820372759924883413e183Q,
+      0.2231192748659813646596607021218715118256e185Q,
+      0.2543559733472187557120132004189335234812e187Q,
+      0.2925093693493015690688151804817735520034e189Q,
+      0.339310868445189820119825609358857320324e191Q,
+      0.396993716080872089540195962949863064779e193Q,
+      0.4684525849754290656574312362808384164393e195Q,
+      0.5574585761207605881323431711741977155627e197Q,
+      0.6689502913449127057588118054090372586753e199Q,
+      0.8094298525273443739681622845449350829971e201Q,
+      0.9875044200833601362411579871448208012564e203Q,
+      0.1214630436702532967576624324188129585545e206Q,
+      0.1506141741511140879795014161993280686076e208Q,
+      0.1882677176888926099743767702491600857595e210Q,
+      0.237217324288004688567714730513941708057e212Q,
+      0.3012660018457659544809977077527059692324e214Q,
+      0.3856204823625804217356770659234636406175e216Q,
+      0.4974504222477287440390234150412680963966e218Q,
+      0.6466855489220473672507304395536485253155e220Q,
+      0.8471580690878820510984568758152795681634e222Q,
+      0.1118248651196004307449963076076169029976e225Q,
+      0.1487270706090685728908450891181304809868e227Q,
+      0.1992942746161518876737324194182948445223e229Q,
+      0.269047270731805048359538766214698040105e231Q,
+      0.3659042881952548657689727220519893345429e233Q,
+      0.5012888748274991661034926292112253883237e235Q,
+      0.6917786472619488492228198283114910358867e237Q,
+      0.9615723196941089004197195613529725398826e239Q,
+      0.1346201247571752460587607385894161555836e242Q,
+      0.1898143759076170969428526414110767793728e244Q,
+      0.2695364137888162776588507508037290267094e246Q,
+      0.3854370717180072770521565736493325081944e248Q,
+      0.5550293832739304789551054660550388118e250Q,
+      0.80479260574719919448490292577980627711e252Q,
+      0.1174997204390910823947958271638517164581e255Q,
+      0.1727245890454638911203498659308620231933e257Q,
+      0.2556323917872865588581178015776757943262e259Q,
+      0.380892263763056972698595524350736933546e261Q,
+      0.571338395644585459047893286526105400319e263Q,
+      0.8627209774233240431623188626544191544816e265Q,
+      0.1311335885683452545606724671234717114812e268Q,
+      0.2006343905095682394778288746989117185662e270Q,
+      0.308976961384735088795856467036324046592e272Q,
+      0.4789142901463393876335775239063022722176e274Q,
+      0.7471062926282894447083809372938315446595e276Q,
+      0.1172956879426414428192158071551315525115e279Q,
+      0.1853271869493734796543609753051078529682e281Q,
+      0.2946702272495038326504339507351214862195e283Q,
+      0.4714723635992061322406943211761943779512e285Q,
+      0.7590705053947218729075178570936729485014e287Q,
+      0.1229694218739449434110178928491750176572e290Q,
+      0.2004401576545302577599591653441552787813e292Q,
+      0.3287218585534296227263330311644146572013e294Q,
+      0.5423910666131588774984495014212841843822e296Q,
+      0.9003691705778437366474261723593317460744e298Q,
+      0.1503616514864999040201201707840084015944e301Q,
+      0.2526075744973198387538018869171341146786e303Q,
+      0.4269068009004705274939251888899566538069e305Q,
+      0.7257415615307998967396728211129263114717e307Q,
+   } };
+
+   return factorials[i];
+}
+
+template <>
+struct max_factorial<BOOST_MATH_FLOAT128_TYPE>
+{
+   BOOST_STATIC_CONSTANT(unsigned, value = 170);
+};
+
+#endif
+
+template <>
+inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION double unchecked_factorial<double>(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(double))
+{
+   return static_cast<double>(boost::math::unchecked_factorial<long double>(i));
+}
+
+template <>
+struct max_factorial<double>
+{
+   BOOST_STATIC_CONSTANT(unsigned,
+      value = ::boost::math::max_factorial<long double>::value);
+};
+
+#ifndef BOOST_MATH_NO_LEXICAL_CAST
+
+template <class T>
+struct unchecked_factorial_initializer
+{
+   struct init
+   {
+      init()
+      {
+         boost::math::unchecked_factorial<T>(3);
+      }
+      void force_instantiate()const {}
+   };
+   static const init initializer;
+   static void force_instantiate()
+   {
+      initializer.force_instantiate();
+   }
+};
+
+template <class T>
+const typename unchecked_factorial_initializer<T>::init unchecked_factorial_initializer<T>::initializer;
+
+
+template <class T, int N>
+inline T unchecked_factorial_imp(unsigned i, const boost::integral_constant<int, N>&)
+{
+   BOOST_STATIC_ASSERT(!boost::is_integral<T>::value);
+   // factorial<unsigned int>(n) is not implemented
+   // because it would overflow integral type T for too small n
+   // to be useful. Use instead a floating-point type,
+   // and convert to an unsigned type if essential, for example:
+   // unsigned int nfac = static_cast<unsigned int>(factorial<double>(n));
+   // See factorial documentation for more detail.
+
+   unchecked_factorial_initializer<T>::force_instantiate();
+
+   static const boost::array<T, 101> factorials = {{
+      T(boost::math::tools::convert_from_string<T>("1")),
+      T(boost::math::tools::convert_from_string<T>("1")),
+      T(boost::math::tools::convert_from_string<T>("2")),
+      T(boost::math::tools::convert_from_string<T>("6")),
+      T(boost::math::tools::convert_from_string<T>("24")),
+      T(boost::math::tools::convert_from_string<T>("120")),
+      T(boost::math::tools::convert_from_string<T>("720")),
+      T(boost::math::tools::convert_from_string<T>("5040")),
+      T(boost::math::tools::convert_from_string<T>("40320")),
+      T(boost::math::tools::convert_from_string<T>("362880")),
+      T(boost::math::tools::convert_from_string<T>("3628800")),
+      T(boost::math::tools::convert_from_string<T>("39916800")),
+      T(boost::math::tools::convert_from_string<T>("479001600")),
+      T(boost::math::tools::convert_from_string<T>("6227020800")),
+      T(boost::math::tools::convert_from_string<T>("87178291200")),
+      T(boost::math::tools::convert_from_string<T>("1307674368000")),
+      T(boost::math::tools::convert_from_string<T>("20922789888000")),
+      T(boost::math::tools::convert_from_string<T>("355687428096000")),
+      T(boost::math::tools::convert_from_string<T>("6402373705728000")),
+      T(boost::math::tools::convert_from_string<T>("121645100408832000")),
+      T(boost::math::tools::convert_from_string<T>("2432902008176640000")),
+      T(boost::math::tools::convert_from_string<T>("51090942171709440000")),
+      T(boost::math::tools::convert_from_string<T>("1124000727777607680000")),
+      T(boost::math::tools::convert_from_string<T>("25852016738884976640000")),
+      T(boost::math::tools::convert_from_string<T>("620448401733239439360000")),
+      T(boost::math::tools::convert_from_string<T>("15511210043330985984000000")),
+      T(boost::math::tools::convert_from_string<T>("403291461126605635584000000")),
+      T(boost::math::tools::convert_from_string<T>("10888869450418352160768000000")),
+      T(boost::math::tools::convert_from_string<T>("304888344611713860501504000000")),
+      T(boost::math::tools::convert_from_string<T>("8841761993739701954543616000000")),
+      T(boost::math::tools::convert_from_string<T>("265252859812191058636308480000000")),
+      T(boost::math::tools::convert_from_string<T>("8222838654177922817725562880000000")),
+      T(boost::math::tools::convert_from_string<T>("263130836933693530167218012160000000")),
+      T(boost::math::tools::convert_from_string<T>("8683317618811886495518194401280000000")),
+      T(boost::math::tools::convert_from_string<T>("295232799039604140847618609643520000000")),
+      T(boost::math::tools::convert_from_string<T>("10333147966386144929666651337523200000000")),
+      T(boost::math::tools::convert_from_string<T>("371993326789901217467999448150835200000000")),
+      T(boost::math::tools::convert_from_string<T>("13763753091226345046315979581580902400000000")),
+      T(boost::math::tools::convert_from_string<T>("523022617466601111760007224100074291200000000")),
+      T(boost::math::tools::convert_from_string<T>("20397882081197443358640281739902897356800000000")),
+      T(boost::math::tools::convert_from_string<T>("815915283247897734345611269596115894272000000000")),
+      T(boost::math::tools::convert_from_string<T>("33452526613163807108170062053440751665152000000000")),
+      T(boost::math::tools::convert_from_string<T>("1405006117752879898543142606244511569936384000000000")),
+      T(boost::math::tools::convert_from_string<T>("60415263063373835637355132068513997507264512000000000")),
+      T(boost::math::tools::convert_from_string<T>("2658271574788448768043625811014615890319638528000000000")),
+      T(boost::math::tools::convert_from_string<T>("119622220865480194561963161495657715064383733760000000000")),
+      T(boost::math::tools::convert_from_string<T>("5502622159812088949850305428800254892961651752960000000000")),
+      T(boost::math::tools::convert_from_string<T>("258623241511168180642964355153611979969197632389120000000000")),
+      T(boost::math::tools::convert_from_string<T>("12413915592536072670862289047373375038521486354677760000000000")),
+      T(boost::math::tools::convert_from_string<T>("608281864034267560872252163321295376887552831379210240000000000")),
+      T(boost::math::tools::convert_from_string<T>("30414093201713378043612608166064768844377641568960512000000000000")),
+      T(boost::math::tools::convert_from_string<T>("1551118753287382280224243016469303211063259720016986112000000000000")),
+      T(boost::math::tools::convert_from_string<T>("80658175170943878571660636856403766975289505440883277824000000000000")),
+      T(boost::math::tools::convert_from_string<T>("4274883284060025564298013753389399649690343788366813724672000000000000")),
+      T(boost::math::tools::convert_from_string<T>("230843697339241380472092742683027581083278564571807941132288000000000000")),
+      T(boost::math::tools::convert_from_string<T>("12696403353658275925965100847566516959580321051449436762275840000000000000")),
+      T(boost::math::tools::convert_from_string<T>("710998587804863451854045647463724949736497978881168458687447040000000000000")),
+      T(boost::math::tools::convert_from_string<T>("40526919504877216755680601905432322134980384796226602145184481280000000000000")),
+      T(boost::math::tools::convert_from_string<T>("2350561331282878571829474910515074683828862318181142924420699914240000000000000")),
+      T(boost::math::tools::convert_from_string<T>("138683118545689835737939019720389406345902876772687432540821294940160000000000000")),
+      T(boost::math::tools::convert_from_string<T>("8320987112741390144276341183223364380754172606361245952449277696409600000000000000")),
+      T(boost::math::tools::convert_from_string<T>("507580213877224798800856812176625227226004528988036003099405939480985600000000000000")),
+      T(boost::math::tools::convert_from_string<T>("31469973260387937525653122354950764088012280797258232192163168247821107200000000000000")),
+      T(boost::math::tools::convert_from_string<T>("1982608315404440064116146708361898137544773690227268628106279599612729753600000000000000")),
+      T(boost::math::tools::convert_from_string<T>("126886932185884164103433389335161480802865516174545192198801894375214704230400000000000000")),
+      T(boost::math::tools::convert_from_string<T>("8247650592082470666723170306785496252186258551345437492922123134388955774976000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("544344939077443064003729240247842752644293064388798874532860126869671081148416000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("36471110918188685288249859096605464427167635314049524593701628500267962436943872000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("2480035542436830599600990418569171581047399201355367672371710738018221445712183296000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("850478588567862317521167644239926010288584608120796235886430763388588680378079017697280000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("61234458376886086861524070385274672740778091784697328983823014963978384987221689274204160000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("4470115461512684340891257138125051110076800700282905015819080092370422104067183317016903680000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("330788544151938641225953028221253782145683251820934971170611926835411235700971565459250872320000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("24809140811395398091946477116594033660926243886570122837795894512655842677572867409443815424000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("1885494701666050254987932260861146558230394535379329335672487982961844043495537923117729972224000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("11324281178206297831457521158732046228731749579488251990048962825668835325234200766245086213177344000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("894618213078297528685144171539831652069808216779571907213868063227837990693501860533361810841010176000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("5797126020747367985879734231578109105412357244731625958745865049716390179693892056256184534249745940480000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("475364333701284174842138206989404946643813294067993328617160934076743994734899148613007131808479167119360000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("39455239697206586511897471180120610571436503407643446275224357528369751562996629334879591940103770870906880000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("3314240134565353266999387579130131288000666286242049487118846032383059131291716864129885722968716753156177920000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("281710411438055027694947944226061159480056634330574206405101912752560026159795933451040286452340924018275123200000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("24227095383672732381765523203441259715284870552429381750838764496720162249742450276789464634901319465571660595200000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("2107757298379527717213600518699389595229783738061356212322972511214654115727593174080683423236414793504734471782400000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("185482642257398439114796845645546284380220968949399346684421580986889562184028199319100141244804501828416633516851200000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("16507955160908461081216919262453619309839666236496541854913520707833171034378509739399912570787600662729080382999756800000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("1485715964481761497309522733620825737885569961284688766942216863704985393094065876545992131370884059645617234469978112000000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("135200152767840296255166568759495142147586866476906677791741734597153670771559994765685283954750449427751168336768008192000000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("12438414054641307255475324325873553077577991715875414356840239582938137710983519518443046123837041347353107486982656753664000000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("1156772507081641574759205162306240436214753229576413535186142281213246807121467315215203289516844845303838996289387078090752000000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("108736615665674308027365285256786601004186803580182872307497374434045199869417927630229109214583415458560865651202385340530688000000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("10329978488239059262599702099394727095397746340117372869212250571234293987594703124871765375385424468563282236864226607350415360000000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("991677934870949689209571401541893801158183648651267795444376054838492222809091499987689476037000748982075094738965754305639874560000000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("96192759682482119853328425949563698712343813919172976158104477319333745612481875498805879175589072651261284189679678167647067832320000000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("9426890448883247745626185743057242473809693764078951663494238777294707070023223798882976159207729119823605850588608460429412647567360000000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000")),
+      T(boost::math::tools::convert_from_string<T>("93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000")),
+   }};
+
+   return factorials[i];
+}
+
+template <class T>
+inline T unchecked_factorial_imp(unsigned i, const boost::integral_constant<int, 0>&)
+{
+   BOOST_STATIC_ASSERT(!boost::is_integral<T>::value);
+   // factorial<unsigned int>(n) is not implemented
+   // because it would overflow integral type T for too small n
+   // to be useful. Use instead a floating-point type,
+   // and convert to an unsigned type if essential, for example:
+   // unsigned int nfac = static_cast<unsigned int>(factorial<double>(n));
+   // See factorial documentation for more detail.
+#ifdef BOOST_NO_CXX11_THREAD_LOCAL
+   unchecked_factorial_initializer<T>::force_instantiate();
+#endif
+   static const char* const factorial_strings[] = {
+         "1",
+         "1",
+         "2",
+         "6",
+         "24",
+         "120",
+         "720",
+         "5040",
+         "40320",
+         "362880",
+         "3628800",
+         "39916800",
+         "479001600",
+         "6227020800",
+         "87178291200",
+         "1307674368000",
+         "20922789888000",
+         "355687428096000",
+         "6402373705728000",
+         "121645100408832000",
+         "2432902008176640000",
+         "51090942171709440000",
+         "1124000727777607680000",
+         "25852016738884976640000",
+         "620448401733239439360000",
+         "15511210043330985984000000",
+         "403291461126605635584000000",
+         "10888869450418352160768000000",
+         "304888344611713860501504000000",
+         "8841761993739701954543616000000",
+         "265252859812191058636308480000000",
+         "8222838654177922817725562880000000",
+         "263130836933693530167218012160000000",
+         "8683317618811886495518194401280000000",
+         "295232799039604140847618609643520000000",
+         "10333147966386144929666651337523200000000",
+         "371993326789901217467999448150835200000000",
+         "13763753091226345046315979581580902400000000",
+         "523022617466601111760007224100074291200000000",
+         "20397882081197443358640281739902897356800000000",
+         "815915283247897734345611269596115894272000000000",
+         "33452526613163807108170062053440751665152000000000",
+         "1405006117752879898543142606244511569936384000000000",
+         "60415263063373835637355132068513997507264512000000000",
+         "2658271574788448768043625811014615890319638528000000000",
+         "119622220865480194561963161495657715064383733760000000000",
+         "5502622159812088949850305428800254892961651752960000000000",
+         "258623241511168180642964355153611979969197632389120000000000",
+         "12413915592536072670862289047373375038521486354677760000000000",
+         "608281864034267560872252163321295376887552831379210240000000000",
+         "30414093201713378043612608166064768844377641568960512000000000000",
+         "1551118753287382280224243016469303211063259720016986112000000000000",
+         "80658175170943878571660636856403766975289505440883277824000000000000",
+         "4274883284060025564298013753389399649690343788366813724672000000000000",
+         "230843697339241380472092742683027581083278564571807941132288000000000000",
+         "12696403353658275925965100847566516959580321051449436762275840000000000000",
+         "710998587804863451854045647463724949736497978881168458687447040000000000000",
+         "40526919504877216755680601905432322134980384796226602145184481280000000000000",
+         "2350561331282878571829474910515074683828862318181142924420699914240000000000000",
+         "138683118545689835737939019720389406345902876772687432540821294940160000000000000",
+         "8320987112741390144276341183223364380754172606361245952449277696409600000000000000",
+         "507580213877224798800856812176625227226004528988036003099405939480985600000000000000",
+         "31469973260387937525653122354950764088012280797258232192163168247821107200000000000000",
+         "1982608315404440064116146708361898137544773690227268628106279599612729753600000000000000",
+         "126886932185884164103433389335161480802865516174545192198801894375214704230400000000000000",
+         "8247650592082470666723170306785496252186258551345437492922123134388955774976000000000000000",
+         "544344939077443064003729240247842752644293064388798874532860126869671081148416000000000000000",
+         "36471110918188685288249859096605464427167635314049524593701628500267962436943872000000000000000",
+         "2480035542436830599600990418569171581047399201355367672371710738018221445712183296000000000000000",
+         "171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000",
+         "11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000",
+         "850478588567862317521167644239926010288584608120796235886430763388588680378079017697280000000000000000",
+         "61234458376886086861524070385274672740778091784697328983823014963978384987221689274204160000000000000000",
+         "4470115461512684340891257138125051110076800700282905015819080092370422104067183317016903680000000000000000",
+         "330788544151938641225953028221253782145683251820934971170611926835411235700971565459250872320000000000000000",
+         "24809140811395398091946477116594033660926243886570122837795894512655842677572867409443815424000000000000000000",
+         "1885494701666050254987932260861146558230394535379329335672487982961844043495537923117729972224000000000000000000",
+         "145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000",
+         "11324281178206297831457521158732046228731749579488251990048962825668835325234200766245086213177344000000000000000000",
+         "894618213078297528685144171539831652069808216779571907213868063227837990693501860533361810841010176000000000000000000",
+         "71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000",
+         "5797126020747367985879734231578109105412357244731625958745865049716390179693892056256184534249745940480000000000000000000",
+         "475364333701284174842138206989404946643813294067993328617160934076743994734899148613007131808479167119360000000000000000000",
+         "39455239697206586511897471180120610571436503407643446275224357528369751562996629334879591940103770870906880000000000000000000",
+         "3314240134565353266999387579130131288000666286242049487118846032383059131291716864129885722968716753156177920000000000000000000",
+         "281710411438055027694947944226061159480056634330574206405101912752560026159795933451040286452340924018275123200000000000000000000",
+         "24227095383672732381765523203441259715284870552429381750838764496720162249742450276789464634901319465571660595200000000000000000000",
+         "2107757298379527717213600518699389595229783738061356212322972511214654115727593174080683423236414793504734471782400000000000000000000",
+         "185482642257398439114796845645546284380220968949399346684421580986889562184028199319100141244804501828416633516851200000000000000000000",
+         "16507955160908461081216919262453619309839666236496541854913520707833171034378509739399912570787600662729080382999756800000000000000000000",
+         "1485715964481761497309522733620825737885569961284688766942216863704985393094065876545992131370884059645617234469978112000000000000000000000",
+         "135200152767840296255166568759495142147586866476906677791741734597153670771559994765685283954750449427751168336768008192000000000000000000000",
+         "12438414054641307255475324325873553077577991715875414356840239582938137710983519518443046123837041347353107486982656753664000000000000000000000",
+         "1156772507081641574759205162306240436214753229576413535186142281213246807121467315215203289516844845303838996289387078090752000000000000000000000",
+         "108736615665674308027365285256786601004186803580182872307497374434045199869417927630229109214583415458560865651202385340530688000000000000000000000",
+         "10329978488239059262599702099394727095397746340117372869212250571234293987594703124871765375385424468563282236864226607350415360000000000000000000000",
+         "991677934870949689209571401541893801158183648651267795444376054838492222809091499987689476037000748982075094738965754305639874560000000000000000000000",
+         "96192759682482119853328425949563698712343813919172976158104477319333745612481875498805879175589072651261284189679678167647067832320000000000000000000000",
+         "9426890448883247745626185743057242473809693764078951663494238777294707070023223798882976159207729119823605850588608460429412647567360000000000000000000000",
+         "933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000",
+         "93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000",
+      };
+
+      static BOOST_MATH_THREAD_LOCAL T factorials[sizeof(factorial_strings) / sizeof(factorial_strings[0])];
+      static BOOST_MATH_THREAD_LOCAL int digits = 0;
+
+      int current_digits = boost::math::tools::digits<T>();
+
+      if(digits != current_digits)
+      {
+         digits = current_digits;
+         for(unsigned k = 0; k < sizeof(factorials) / sizeof(factorials[0]); ++k)
+            factorials[k] = static_cast<T>(boost::math::tools::convert_from_string<T>(factorial_strings[k]));
+      }
+
+   return factorials[i];
+}
+
+template <class T>
+inline T unchecked_factorial_imp(unsigned i, const boost::integral_constant<int, std::numeric_limits<float>::digits>&)
+{
+   return unchecked_factorial<float>(i);
+}
+
+template <class T>
+inline T unchecked_factorial_imp(unsigned i, const boost::integral_constant<int, std::numeric_limits<double>::digits>&)
+{
+   return unchecked_factorial<double>(i);
+}
+
+#if DBL_MANT_DIG != LDBL_MANT_DIG
+template <class T>
+inline T unchecked_factorial_imp(unsigned i, const boost::integral_constant<int, LDBL_MANT_DIG>&)
+{
+   return unchecked_factorial<long double>(i);
+}
+#endif
+#ifdef BOOST_MATH_USE_FLOAT128
+template <class T>
+inline T unchecked_factorial_imp(unsigned i, const boost::integral_constant<int, 113>&)
+{
+   return unchecked_factorial<BOOST_MATH_FLOAT128_TYPE>(i);
+}
+#endif
+
+template <class T>
+inline T unchecked_factorial(unsigned i)
+{
+   typedef typename boost::math::policies::precision<T, boost::math::policies::policy<> >::type tag_type;
+   return unchecked_factorial_imp<T>(i, tag_type());
+}
+
+#ifdef BOOST_MATH_USE_FLOAT128
+#define BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL : std::numeric_limits<T>::digits == 113 ? max_factorial<BOOST_MATH_FLOAT128_TYPE>::value
+#else
+#define BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL
+#endif
+
+template <class T>
+struct max_factorial
+{
+   BOOST_STATIC_CONSTANT(unsigned, value = 
+      std::numeric_limits<T>::digits == std::numeric_limits<float>::digits ? max_factorial<float>::value 
+      : std::numeric_limits<T>::digits == std::numeric_limits<double>::digits ? max_factorial<double>::value 
+      : std::numeric_limits<T>::digits == std::numeric_limits<long double>::digits ? max_factorial<long double>::value 
+      BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL
+      : 100);
+};
+
+#undef BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL
+
+#else // BOOST_MATH_NO_LEXICAL_CAST
+
+template <class T>
+inline T unchecked_factorial(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
+{
+   return 1;
+}
+
+template <class T>
+struct max_factorial
+{
+   BOOST_STATIC_CONSTANT(unsigned, value = 0);
+};
+
+#endif
+
+#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
+template <class T>
+const unsigned max_factorial<T>::value;
+#endif
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_SP_UC_FACTORIALS_HPP
+
diff --git a/ThirdParty/boost/math/special_functions/digamma.hpp b/ThirdParty/boost/math/special_functions/digamma.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2cd752492a5639223927f786b6e589f281a6f34d
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/digamma.hpp
@@ -0,0 +1,630 @@
+//  (C) Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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_SF_DIGAMMA_HPP
+#define BOOST_MATH_SF_DIGAMMA_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#pragma warning(push)
+#pragma warning(disable:4702) // Unreachable code (release mode only warning)
+#endif
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/tools/rational.hpp>
+#include <boost/math/tools/series.hpp>
+#include <boost/math/tools/promotion.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/constants/constants.hpp>
+#include <boost/mpl/comparison.hpp>
+#include <boost/math/tools/big_constant.hpp>
+
+#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128)
+//
+// This is the only way we can avoid
+// warning: non-standard suffix on floating constant [-Wpedantic]
+// when building with -Wall -pedantic.  Neither __extension__
+// nor #pragma diagnostic ignored work :(
+//
+#pragma GCC system_header
+#endif
+
+namespace boost{
+namespace math{
+namespace detail{
+//
+// Begin by defining the smallest value for which it is safe to
+// use the asymptotic expansion for digamma:
+//
+inline unsigned digamma_large_lim(const boost::integral_constant<int, 0>*)
+{  return 20;  }
+inline unsigned digamma_large_lim(const boost::integral_constant<int, 113>*)
+{  return 20;  }
+inline unsigned digamma_large_lim(const void*)
+{  return 10;  }
+//
+// Implementations of the asymptotic expansion come next,
+// the coefficients of the series have been evaluated
+// in advance at high precision, and the series truncated
+// at the first term that's too small to effect the result.
+// Note that the series becomes divergent after a while
+// so truncation is very important.
+//
+// This first one gives 34-digit precision for x >= 20:
+//
+template <class T>
+inline T digamma_imp_large(T x, const boost::integral_constant<int, 113>*)
+{
+   BOOST_MATH_STD_USING // ADL of std functions.
+   static const T P[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.083333333333333333333333333333333333333333333333333),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.0083333333333333333333333333333333333333333333333333),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.003968253968253968253968253968253968253968253968254),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.0041666666666666666666666666666666666666666666666667),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.0075757575757575757575757575757575757575757575757576),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.021092796092796092796092796092796092796092796092796),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.083333333333333333333333333333333333333333333333333),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.44325980392156862745098039215686274509803921568627),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 3.0539543302701197438039543302701197438039543302701),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -26.456212121212121212121212121212121212121212121212),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 281.4601449275362318840579710144927536231884057971),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -3607.510546398046398046398046398046398046398046398),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 54827.583333333333333333333333333333333333333333333),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -974936.82385057471264367816091954022988505747126437),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 20052695.796688078946143462272494530559046688078946),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -472384867.72162990196078431372549019607843137254902),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 12635724795.916666666666666666666666666666666666667)
+   };
+   x -= 1;
+   T result = log(x);
+   result += 1 / (2 * x);
+   T z = 1 / (x*x);
+   result -= z * tools::evaluate_polynomial(P, z);
+   return result;
+}
+//
+// 19-digit precision for x >= 10:
+//
+template <class T>
+inline T digamma_imp_large(T x, const boost::integral_constant<int, 64>*)
+{
+   BOOST_MATH_STD_USING // ADL of std functions.
+   static const T P[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.083333333333333333333333333333333333333333333333333),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.0083333333333333333333333333333333333333333333333333),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.003968253968253968253968253968253968253968253968254),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.0041666666666666666666666666666666666666666666666667),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.0075757575757575757575757575757575757575757575757576),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.021092796092796092796092796092796092796092796092796),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.083333333333333333333333333333333333333333333333333),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.44325980392156862745098039215686274509803921568627),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 3.0539543302701197438039543302701197438039543302701),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -26.456212121212121212121212121212121212121212121212),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 281.4601449275362318840579710144927536231884057971),
+   };
+   x -= 1;
+   T result = log(x);
+   result += 1 / (2 * x);
+   T z = 1 / (x*x);
+   result -= z * tools::evaluate_polynomial(P, z);
+   return result;
+}
+//
+// 17-digit precision for x >= 10:
+//
+template <class T>
+inline T digamma_imp_large(T x, const boost::integral_constant<int, 53>*)
+{
+   BOOST_MATH_STD_USING // ADL of std functions.
+   static const T P[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 53, 0.083333333333333333333333333333333333333333333333333),
+      BOOST_MATH_BIG_CONSTANT(T, 53, -0.0083333333333333333333333333333333333333333333333333),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 0.003968253968253968253968253968253968253968253968254),
+      BOOST_MATH_BIG_CONSTANT(T, 53, -0.0041666666666666666666666666666666666666666666666667),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 0.0075757575757575757575757575757575757575757575757576),
+      BOOST_MATH_BIG_CONSTANT(T, 53, -0.021092796092796092796092796092796092796092796092796),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 0.083333333333333333333333333333333333333333333333333),
+      BOOST_MATH_BIG_CONSTANT(T, 53, -0.44325980392156862745098039215686274509803921568627)
+   };
+   x -= 1;
+   T result = log(x);
+   result += 1 / (2 * x);
+   T z = 1 / (x*x);
+   result -= z * tools::evaluate_polynomial(P, z);
+   return result;
+}
+//
+// 9-digit precision for x >= 10:
+//
+template <class T>
+inline T digamma_imp_large(T x, const boost::integral_constant<int, 24>*)
+{
+   BOOST_MATH_STD_USING // ADL of std functions.
+   static const T P[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 24, 0.083333333333333333333333333333333333333333333333333),
+      BOOST_MATH_BIG_CONSTANT(T, 24, -0.0083333333333333333333333333333333333333333333333333),
+      BOOST_MATH_BIG_CONSTANT(T, 24, 0.003968253968253968253968253968253968253968253968254)
+   };
+   x -= 1;
+   T result = log(x);
+   result += 1 / (2 * x);
+   T z = 1 / (x*x);
+   result -= z * tools::evaluate_polynomial(P, z);
+   return result;
+}
+//
+// Fully generic asymptotic expansion in terms of Bernoulli numbers, see:
+// http://functions.wolfram.com/06.14.06.0012.01
+//
+template <class T>
+struct digamma_series_func
+{
+private:
+   int k;
+   T xx;
+   T term;
+public:
+   digamma_series_func(T x) : k(1), xx(x * x), term(1 / (x * x)) {}
+   T operator()()
+   {
+      T result = term * boost::math::bernoulli_b2n<T>(k) / (2 * k);
+      term /= xx;
+      ++k;
+      return result;
+   }
+   typedef T result_type;
+};
+
+template <class T, class Policy>
+inline T digamma_imp_large(T x, const Policy& pol, const boost::integral_constant<int, 0>*)
+{
+   BOOST_MATH_STD_USING
+   digamma_series_func<T> s(x);
+   T result = log(x) - 1 / (2 * x);
+   boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
+   result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter, -result);
+   result = -result;
+   policies::check_series_iterations<T>("boost::math::digamma<%1%>(%1%)", max_iter, pol);
+   return result;
+}
+//
+// Now follow rational approximations over the range [1,2].
+//
+// 35-digit precision:
+//
+template <class T>
+T digamma_imp_1_2(T x, const boost::integral_constant<int, 113>*)
+{
+   //
+   // Now the approximation, we use the form:
+   //
+   // digamma(x) = (x - root) * (Y + R(x-1))
+   //
+   // Where root is the location of the positive root of digamma,
+   // Y is a constant, and R is optimised for low absolute error
+   // compared to Y.
+   //
+   // Max error found at 128-bit long double precision:  5.541e-35
+   // Maximum Deviation Found (approximation error):     1.965e-35
+   //
+   static const float Y = 0.99558162689208984375F;
+
+   static const T root1 = T(1569415565) / 1073741824uL;
+   static const T root2 = (T(381566830) / 1073741824uL) / 1073741824uL;
+   static const T root3 = ((T(111616537) / 1073741824uL) / 1073741824uL) / 1073741824uL;
+   static const T root4 = (((T(503992070) / 1073741824uL) / 1073741824uL) / 1073741824uL) / 1073741824uL;
+   static const T root5 = BOOST_MATH_BIG_CONSTANT(T, 113, 0.52112228569249997894452490385577338504019838794544e-36);
+
+   static const T P[] = {    
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.25479851061131551526977464225335883769),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.18684290534374944114622235683619897417),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.80360876047931768958995775910991929922),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.67227342794829064330498117008564270136),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.26569010991230617151285010695543858005),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.05775672694575986971640757748003553385),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.0071432147823164975485922555833274240665),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.00048740753910766168912364555706064993274),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.16454996865214115723416538844975174761e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.20327832297631728077731148515093164955e-6)
+   };
+   static const T Q[] = {    
+      BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 2.6210924610812025425088411043163287646),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 2.6850757078559596612621337395886392594),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 1.4320913706209965531250495490639289418),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.4410872083455009362557012239501953402),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.081385727399251729505165509278152487225),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.0089478633066857163432104815183858149496),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.00055861622855066424871506755481997374154),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.1760168552357342401304462967950178554e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.20585454493572473724556649516040874384e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.90745971844439990284514121823069162795e-11),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.48857673606545846774761343500033283272e-13),
+   };
+   T g = x - root1;
+   g -= root2;
+   g -= root3;
+   g -= root4;
+   g -= root5;
+   T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1));
+   T result = g * Y + g * r;
+
+   return result;
+}
+//
+// 19-digit precision:
+//
+template <class T>
+T digamma_imp_1_2(T x, const boost::integral_constant<int, 64>*)
+{
+   //
+   // Now the approximation, we use the form:
+   //
+   // digamma(x) = (x - root) * (Y + R(x-1))
+   //
+   // Where root is the location of the positive root of digamma,
+   // Y is a constant, and R is optimised for low absolute error
+   // compared to Y.
+   //
+   // Max error found at 80-bit long double precision:   5.016e-20
+   // Maximum Deviation Found (approximation error):     3.575e-20
+   //
+   static const float Y = 0.99558162689208984375F;
+
+   static const T root1 = T(1569415565) / 1073741824uL;
+   static const T root2 = (T(381566830) / 1073741824uL) / 1073741824uL;
+   static const T root3 = BOOST_MATH_BIG_CONSTANT(T, 64, 0.9016312093258695918615325266959189453125e-19);
+
+   static const T P[] = {    
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.254798510611315515235),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.314628554532916496608),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.665836341559876230295),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.314767657147375752913),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.0541156266153505273939),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.00289268368333918761452)
+   };
+   static const T Q[] = {    
+      BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 2.1195759927055347547),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 1.54350554664961128724),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.486986018231042975162),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.0660481487173569812846),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.00298999662592323990972),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.165079794012604905639e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.317940243105952177571e-7)
+   };
+   T g = x - root1;
+   g -= root2;
+   g -= root3;
+   T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1));
+   T result = g * Y + g * r;
+
+   return result;
+}
+//
+// 18-digit precision:
+//
+template <class T>
+T digamma_imp_1_2(T x, const boost::integral_constant<int, 53>*)
+{
+   //
+   // Now the approximation, we use the form:
+   //
+   // digamma(x) = (x - root) * (Y + R(x-1))
+   //
+   // Where root is the location of the positive root of digamma,
+   // Y is a constant, and R is optimised for low absolute error
+   // compared to Y.
+   //
+   // Maximum Deviation Found:               1.466e-18
+   // At double precision, max error found:  2.452e-17
+   //
+   static const float Y = 0.99558162689208984F;
+
+   static const T root1 = T(1569415565) / 1073741824uL;
+   static const T root2 = (T(381566830) / 1073741824uL) / 1073741824uL;
+   static const T root3 = BOOST_MATH_BIG_CONSTANT(T, 53, 0.9016312093258695918615325266959189453125e-19);
+
+   static const T P[] = {    
+      BOOST_MATH_BIG_CONSTANT(T, 53, 0.25479851061131551),
+      BOOST_MATH_BIG_CONSTANT(T, 53, -0.32555031186804491),
+      BOOST_MATH_BIG_CONSTANT(T, 53, -0.65031853770896507),
+      BOOST_MATH_BIG_CONSTANT(T, 53, -0.28919126444774784),
+      BOOST_MATH_BIG_CONSTANT(T, 53, -0.045251321448739056),
+      BOOST_MATH_BIG_CONSTANT(T, 53, -0.0020713321167745952)
+   };
+   static const T Q[] = {    
+      BOOST_MATH_BIG_CONSTANT(T, 53, 1.0),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 2.0767117023730469),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 1.4606242909763515),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 0.43593529692665969),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 0.054151797245674225),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 0.0021284987017821144),
+      BOOST_MATH_BIG_CONSTANT(T, 53, -0.55789841321675513e-6)
+   };
+   T g = x - root1;
+   g -= root2;
+   g -= root3;
+   T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1));
+   T result = g * Y + g * r;
+
+   return result;
+}
+//
+// 9-digit precision:
+//
+template <class T>
+inline T digamma_imp_1_2(T x, const boost::integral_constant<int, 24>*)
+{
+   //
+   // Now the approximation, we use the form:
+   //
+   // digamma(x) = (x - root) * (Y + R(x-1))
+   //
+   // Where root is the location of the positive root of digamma,
+   // Y is a constant, and R is optimised for low absolute error
+   // compared to Y.
+   //
+   // Maximum Deviation Found:              3.388e-010
+   // At float precision, max error found:  2.008725e-008
+   //
+   static const float Y = 0.99558162689208984f;
+   static const T root = 1532632.0f / 1048576;
+   static const T root_minor = static_cast<T>(0.3700660185912626595423257213284682051735604e-6L);
+   static const T P[] = {    
+      0.25479851023250261e0f,
+      -0.44981331915268368e0f,
+      -0.43916936919946835e0f,
+      -0.61041765350579073e-1f
+   };
+   static const T Q[] = {    
+      0.1e1,
+      0.15890202430554952e1f,
+      0.65341249856146947e0f,
+      0.63851690523355715e-1f
+   };
+   T g = x - root;
+   g -= root_minor;
+   T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1));
+   T result = g * Y + g * r;
+
+   return result;
+}
+
+template <class T, class Tag, class Policy>
+T digamma_imp(T x, const Tag* t, const Policy& pol)
+{
+   //
+   // This handles reflection of negative arguments, and all our
+   // error handling, then forwards to the T-specific approximation.
+   //
+   BOOST_MATH_STD_USING // ADL of std functions.
+
+   T result = 0;
+   //
+   // Check for negative arguments and use reflection:
+   //
+   if(x <= -1)
+   {
+      // Reflect:
+      x = 1 - x;
+      // Argument reduction for tan:
+      T remainder = x - floor(x);
+      // Shift to negative if > 0.5:
+      if(remainder > 0.5)
+      {
+         remainder -= 1;
+      }
+      //
+      // check for evaluation at a negative pole:
+      //
+      if(remainder == 0)
+      {
+         return policies::raise_pole_error<T>("boost::math::digamma<%1%>(%1%)", 0, (1-x), pol);
+      }
+      result = constants::pi<T>() / tan(constants::pi<T>() * remainder);
+   }
+   if(x == 0)
+      return policies::raise_pole_error<T>("boost::math::digamma<%1%>(%1%)", 0, x, pol);
+   //
+   // If we're above the lower-limit for the
+   // asymptotic expansion then use it:
+   //
+   if(x >= digamma_large_lim(t))
+   {
+      result += digamma_imp_large(x, t);
+   }
+   else
+   {
+      //
+      // If x > 2 reduce to the interval [1,2]:
+      //
+      while(x > 2)
+      {
+         x -= 1;
+         result += 1/x;
+      }
+      //
+      // If x < 1 use recurrence to shift to > 1:
+      //
+      while(x < 1)
+      {
+         result -= 1/x;
+         x += 1;
+      }
+      result += digamma_imp_1_2(x, t);
+   }
+   return result;
+}
+
+template <class T, class Policy>
+T digamma_imp(T x, const boost::integral_constant<int, 0>* t, const Policy& pol)
+{
+   //
+   // This handles reflection of negative arguments, and all our
+   // error handling, then forwards to the T-specific approximation.
+   //
+   BOOST_MATH_STD_USING // ADL of std functions.
+
+   T result = 0;
+   //
+   // Check for negative arguments and use reflection:
+   //
+   if(x <= -1)
+   {
+      // Reflect:
+      x = 1 - x;
+      // Argument reduction for tan:
+      T remainder = x - floor(x);
+      // Shift to negative if > 0.5:
+      if(remainder > 0.5)
+      {
+         remainder -= 1;
+      }
+      //
+      // check for evaluation at a negative pole:
+      //
+      if(remainder == 0)
+      {
+         return policies::raise_pole_error<T>("boost::math::digamma<%1%>(%1%)", 0, (1 - x), pol);
+      }
+      result = constants::pi<T>() / tan(constants::pi<T>() * remainder);
+   }
+   if(x == 0)
+      return policies::raise_pole_error<T>("boost::math::digamma<%1%>(%1%)", 0, x, pol);
+   //
+   // If we're above the lower-limit for the
+   // asymptotic expansion then use it, the
+   // limit is a linear interpolation with
+   // limit = 10 at 50 bit precision and
+   // limit = 250 at 1000 bit precision.
+   //
+   int lim = 10 + ((tools::digits<T>() - 50) * 240L) / 950;
+   T two_x = ldexp(x, 1);
+   if(x >= lim)
+   {
+      result += digamma_imp_large(x, pol, t);
+   }
+   else if(floor(x) == x)
+   {
+      //
+      // Special case for integer arguments, see
+      // http://functions.wolfram.com/06.14.03.0001.01
+      //
+      result = -constants::euler<T, Policy>();
+      T val = 1;
+      while(val < x)
+      {
+         result += 1 / val;
+         val += 1;
+      }
+   }
+   else if(floor(two_x) == two_x)
+   {
+      //
+      // Special case for half integer arguments, see:
+      // http://functions.wolfram.com/06.14.03.0007.01
+      //
+      result = -2 * constants::ln_two<T, Policy>() - constants::euler<T, Policy>();
+      int n = itrunc(x);
+      if(n)
+      {
+         for(int k = 1; k < n; ++k)
+            result += 1 / T(k);
+         for(int k = n; k <= 2 * n - 1; ++k)
+            result += 2 / T(k);
+      }
+   }
+   else
+   {
+      //
+      // Rescale so we can use the asymptotic expansion:
+      //
+      while(x < lim)
+      {
+         result -= 1 / x;
+         x += 1;
+      }
+      result += digamma_imp_large(x, pol, t);
+   }
+   return result;
+}
+//
+// Initializer: ensure all our constants are initialized prior to the first call of main:
+//
+template <class T, class Policy>
+struct digamma_initializer
+{
+   struct init
+   {
+      init()
+      {
+         typedef typename policies::precision<T, Policy>::type precision_type;
+         do_init(boost::integral_constant<bool, precision_type::value && (precision_type::value <= 113)>());
+      }
+      void do_init(const boost::true_type&)
+      {
+         boost::math::digamma(T(1.5), Policy());
+         boost::math::digamma(T(500), Policy());
+      }
+      void do_init(const false_type&){}
+      void force_instantiate()const{}
+   };
+   static const init initializer;
+   static void force_instantiate()
+   {
+      initializer.force_instantiate();
+   }
+};
+
+template <class T, class Policy>
+const typename digamma_initializer<T, Policy>::init digamma_initializer<T, Policy>::initializer;
+
+} // namespace detail
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type 
+   digamma(T x, const Policy&)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   typedef typename policies::precision<T, Policy>::type precision_type;
+   typedef boost::integral_constant<int,
+      (precision_type::value <= 0) || (precision_type::value > 113) ? 0 :
+      precision_type::value <= 24 ? 24 :
+      precision_type::value <= 53 ? 53 :
+      precision_type::value <= 64 ? 64 :
+      precision_type::value <= 113 ? 113 : 0 > tag_type;
+   typedef typename policies::normalise<
+      Policy,
+      policies::promote_float<false>,
+      policies::promote_double<false>,
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   // Force initialization of constants:
+   detail::digamma_initializer<value_type, forwarding_policy>::force_instantiate();
+
+   return policies::checked_narrowing_cast<result_type, Policy>(detail::digamma_imp(
+      static_cast<value_type>(x),
+      static_cast<const tag_type*>(0), forwarding_policy()), "boost::math::digamma<%1%>(%1%)");
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type 
+   digamma(T x)
+{
+   return digamma(x, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif
+
diff --git a/ThirdParty/boost/math/special_functions/erf.hpp b/ThirdParty/boost/math/special_functions/erf.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..761e1e945d65d9a44c2fbf0eda8fc025e577c5c3
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/erf.hpp
@@ -0,0 +1,1246 @@
+//  (C) Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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_SPECIAL_ERF_HPP
+#define BOOST_MATH_SPECIAL_ERF_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/tools/config.hpp>
+#include <boost/math/special_functions/gamma.hpp>
+#include <boost/math/tools/roots.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/tools/big_constant.hpp>
+
+#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128)
+//
+// This is the only way we can avoid
+// warning: non-standard suffix on floating constant [-Wpedantic]
+// when building with -Wall -pedantic.  Neither __extension__
+// nor #pragma diagnostic ignored work :(
+//
+#pragma GCC system_header
+#endif
+
+namespace boost{ namespace math{
+
+namespace detail
+{
+
+//
+// Asymptotic series for large z:
+//
+template <class T>
+struct erf_asympt_series_t
+{
+   erf_asympt_series_t(T z) : xx(2 * -z * z), tk(1)
+   {
+      BOOST_MATH_STD_USING
+      result = -exp(-z * z) / sqrt(boost::math::constants::pi<T>());
+      result /= z;
+   }
+
+   typedef T result_type;
+
+   T operator()()
+   {
+      BOOST_MATH_STD_USING
+      T r = result;
+      result *= tk / xx;
+      tk += 2;
+      if( fabs(r) < fabs(result))
+         result = 0;
+      return r;
+   }
+private:
+   T result;
+   T xx;
+   int tk;
+};
+//
+// How large z has to be in order to ensure that the series converges:
+//
+template <class T>
+inline float erf_asymptotic_limit_N(const T&)
+{
+   return (std::numeric_limits<float>::max)();
+}
+inline float erf_asymptotic_limit_N(const boost::integral_constant<int, 24>&)
+{
+   return 2.8F;
+}
+inline float erf_asymptotic_limit_N(const boost::integral_constant<int, 53>&)
+{
+   return 4.3F;
+}
+inline float erf_asymptotic_limit_N(const boost::integral_constant<int, 64>&)
+{
+   return 4.8F;
+}
+inline float erf_asymptotic_limit_N(const boost::integral_constant<int, 106>&)
+{
+   return 6.5F;
+}
+inline float erf_asymptotic_limit_N(const boost::integral_constant<int, 113>&)
+{
+   return 6.8F;
+}
+
+template <class T, class Policy>
+inline T erf_asymptotic_limit()
+{
+   typedef typename policies::precision<T, Policy>::type precision_type;
+   typedef boost::integral_constant<int,
+      precision_type::value <= 0 ? 0 :
+      precision_type::value <= 24 ? 24 :
+      precision_type::value <= 53 ? 53 :
+      precision_type::value <= 64 ? 64 :
+      precision_type::value <= 113 ? 113 : 0
+   > tag_type;
+   return erf_asymptotic_limit_N(tag_type());
+}
+
+template <class T, class Policy, class Tag>
+T erf_imp(T z, bool invert, const Policy& pol, const Tag& t)
+{
+   BOOST_MATH_STD_USING
+
+   BOOST_MATH_INSTRUMENT_CODE("Generic erf_imp called");
+
+   if(z < 0)
+   {
+      if(!invert)
+         return -erf_imp(T(-z), invert, pol, t);
+      else
+         return 1 + erf_imp(T(-z), false, pol, t);
+   }
+
+   T result;
+
+   if(!invert && (z > detail::erf_asymptotic_limit<T, Policy>()))
+   {
+      detail::erf_asympt_series_t<T> s(z);
+      boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
+      result = boost::math::tools::sum_series(s, policies::get_epsilon<T, Policy>(), max_iter, 1);
+      policies::check_series_iterations<T>("boost::math::erf<%1%>(%1%, %1%)", max_iter, pol);
+   }
+   else
+   {
+      T x = z * z;
+      if(x < 0.6)
+      {
+         // Compute P:
+         result = z * exp(-x);
+         result /= sqrt(boost::math::constants::pi<T>());
+         if(result != 0)
+            result *= 2 * detail::lower_gamma_series(T(0.5f), x, pol);
+      }
+      else if(x < 1.1f)
+      {
+         // Compute Q:
+         invert = !invert;
+         result = tgamma_small_upper_part(T(0.5f), x, pol);
+         result /= sqrt(boost::math::constants::pi<T>());
+      }
+      else if(x > 1 / tools::epsilon<T>())
+      {
+         // http://functions.wolfram.com/06.27.06.0006.02
+         invert = !invert;
+         result = exp(-x) / (constants::root_pi<T>() * z);
+      }
+      else
+      {
+         // Compute Q:
+         invert = !invert;
+         result = z * exp(-x);
+         result /= boost::math::constants::root_pi<T>();
+         result *= upper_gamma_fraction(T(0.5f), x, policies::get_epsilon<T, Policy>());
+      }
+   }
+   if(invert)
+      result = 1 - result;
+   return result;
+}
+
+template <class T, class Policy>
+T erf_imp(T z, bool invert, const Policy& pol, const boost::integral_constant<int, 53>& t)
+{
+   BOOST_MATH_STD_USING
+
+   BOOST_MATH_INSTRUMENT_CODE("53-bit precision erf_imp called");
+
+   if ((boost::math::isnan)(z))
+      return policies::raise_denorm_error("boost::math::erf<%1%>(%1%)", "Expected a finite argument but got %1%", z, pol);
+
+   if(z < 0)
+   {
+      if(!invert)
+         return -erf_imp(T(-z), invert, pol, t);
+      else if(z < -0.5)
+         return 2 - erf_imp(T(-z), invert, pol, t);
+      else
+         return 1 + erf_imp(T(-z), false, pol, t);
+   }
+
+   T result;
+
+   //
+   // Big bunch of selection statements now to pick
+   // which implementation to use,
+   // try to put most likely options first:
+   //
+   if(z < 0.5)
+   {
+      //
+      // We're going to calculate erf:
+      //
+      if(z < 1e-10)
+      {
+         if(z == 0)
+         {
+            result = T(0);
+         }
+         else
+         {
+            static const T c = BOOST_MATH_BIG_CONSTANT(T, 53, 0.003379167095512573896158903121545171688);
+            result = static_cast<T>(z * 1.125f + z * c);
+         }
+      }
+      else
+      {
+         // Maximum Deviation Found:                     1.561e-17
+         // Expected Error Term:                         1.561e-17
+         // Maximum Relative Change in Control Points:   1.155e-04
+         // Max Error found at double precision =        2.961182e-17
+
+         static const T Y = 1.044948577880859375f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.0834305892146531832907),
+            BOOST_MATH_BIG_CONSTANT(T, 53, -0.338165134459360935041),
+            BOOST_MATH_BIG_CONSTANT(T, 53, -0.0509990735146777432841),
+            BOOST_MATH_BIG_CONSTANT(T, 53, -0.00772758345802133288487),
+            BOOST_MATH_BIG_CONSTANT(T, 53, -0.000322780120964605683831),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 53, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.455004033050794024546),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.0875222600142252549554),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.00858571925074406212772),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.000370900071787748000569),
+         };
+         T zz = z * z;
+         result = z * (Y + tools::evaluate_polynomial(P, zz) / tools::evaluate_polynomial(Q, zz));
+      }
+   }
+   else if(invert ? (z < 28) : (z < 5.8f))
+   {
+      //
+      // We'll be calculating erfc:
+      //
+      invert = !invert;
+      if(z < 1.5f)
+      {
+         // Maximum Deviation Found:                     3.702e-17
+         // Expected Error Term:                         3.702e-17
+         // Maximum Relative Change in Control Points:   2.845e-04
+         // Max Error found at double precision =        4.841816e-17
+         static const T Y = 0.405935764312744140625f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 53, -0.098090592216281240205),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.178114665841120341155),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.191003695796775433986),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.0888900368967884466578),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.0195049001251218801359),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.00180424538297014223957),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 53, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 1.84759070983002217845),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 1.42628004845511324508),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.578052804889902404909),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.12385097467900864233),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.0113385233577001411017),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.337511472483094676155e-5),
+         };
+         BOOST_MATH_INSTRUMENT_VARIABLE(Y);
+         BOOST_MATH_INSTRUMENT_VARIABLE(P[0]);
+         BOOST_MATH_INSTRUMENT_VARIABLE(Q[0]);
+         BOOST_MATH_INSTRUMENT_VARIABLE(z);
+         result = Y + tools::evaluate_polynomial(P, T(z - 0.5)) / tools::evaluate_polynomial(Q, T(z - 0.5));
+         BOOST_MATH_INSTRUMENT_VARIABLE(result);
+         result *= exp(-z * z) / z;
+         BOOST_MATH_INSTRUMENT_VARIABLE(result);
+      }
+      else if(z < 2.5f)
+      {
+         // Max Error found at double precision =        6.599585e-18
+         // Maximum Deviation Found:                     3.909e-18
+         // Expected Error Term:                         3.909e-18
+         // Maximum Relative Change in Control Points:   9.886e-05
+         static const T Y = 0.50672817230224609375f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 53, -0.0243500476207698441272),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.0386540375035707201728),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.04394818964209516296),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.0175679436311802092299),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.00323962406290842133584),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.000235839115596880717416),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 53, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 1.53991494948552447182),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.982403709157920235114),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.325732924782444448493),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.0563921837420478160373),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.00410369723978904575884),
+         };
+         result = Y + tools::evaluate_polynomial(P, T(z - 1.5)) / tools::evaluate_polynomial(Q, T(z - 1.5));
+         T hi, lo;
+         int expon;
+         hi = floor(ldexp(frexp(z, &expon), 26));
+         hi = ldexp(hi, expon - 26);
+         lo = z - hi;
+         T sq = z * z;
+         T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo;
+         result *= exp(-sq) * exp(-err_sqr) / z;
+      }
+      else if(z < 4.5f)
+      {
+         // Maximum Deviation Found:                     1.512e-17
+         // Expected Error Term:                         1.512e-17
+         // Maximum Relative Change in Control Points:   2.222e-04
+         // Max Error found at double precision =        2.062515e-17
+         static const T Y = 0.5405750274658203125f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.00295276716530971662634),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.0137384425896355332126),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.00840807615555585383007),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.00212825620914618649141),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.000250269961544794627958),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.113212406648847561139e-4),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 53, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 1.04217814166938418171),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.442597659481563127003),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.0958492726301061423444),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.0105982906484876531489),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.000479411269521714493907),
+         };
+         result = Y + tools::evaluate_polynomial(P, T(z - 3.5)) / tools::evaluate_polynomial(Q, T(z - 3.5));
+         T hi, lo;
+         int expon;
+         hi = floor(ldexp(frexp(z, &expon), 26));
+         hi = ldexp(hi, expon - 26);
+         lo = z - hi;
+         T sq = z * z;
+         T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo;
+         result *= exp(-sq) * exp(-err_sqr) / z;
+      }
+      else
+      {
+         // Max Error found at double precision =        2.997958e-17
+         // Maximum Deviation Found:                     2.860e-17
+         // Expected Error Term:                         2.859e-17
+         // Maximum Relative Change in Control Points:   1.357e-05
+         static const T Y = 0.5579090118408203125f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.00628057170626964891937),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 0.0175389834052493308818),
+            BOOST_MATH_BIG_CONSTANT(T, 53, -0.212652252872804219852),
+            BOOST_MATH_BIG_CONSTANT(T, 53, -0.687717681153649930619),
+            BOOST_MATH_BIG_CONSTANT(T, 53, -2.5518551727311523996),
+            BOOST_MATH_BIG_CONSTANT(T, 53, -3.22729451764143718517),
+            BOOST_MATH_BIG_CONSTANT(T, 53, -2.8175401114513378771),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 53, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 2.79257750980575282228),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 11.0567237927800161565),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 15.930646027911794143),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 22.9367376522880577224),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 13.5064170191802889145),
+            BOOST_MATH_BIG_CONSTANT(T, 53, 5.48409182238641741584),
+         };
+         result = Y + tools::evaluate_polynomial(P, T(1 / z)) / tools::evaluate_polynomial(Q, T(1 / z));
+         T hi, lo;
+         int expon;
+         hi = floor(ldexp(frexp(z, &expon), 26));
+         hi = ldexp(hi, expon - 26);
+         lo = z - hi;
+         T sq = z * z;
+         T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo;
+         result *= exp(-sq) * exp(-err_sqr) / z;
+      }
+   }
+   else
+   {
+      //
+      // Any value of z larger than 28 will underflow to zero:
+      //
+      result = 0;
+      invert = !invert;
+   }
+
+   if(invert)
+   {
+      result = 1 - result;
+   }
+
+   return result;
+} // template <class T, class Lanczos>T erf_imp(T z, bool invert, const Lanczos& l, const boost::integral_constant<int, 53>& t)
+
+
+template <class T, class Policy>
+T erf_imp(T z, bool invert, const Policy& pol, const boost::integral_constant<int, 64>& t)
+{
+   BOOST_MATH_STD_USING
+
+   BOOST_MATH_INSTRUMENT_CODE("64-bit precision erf_imp called");
+
+   if(z < 0)
+   {
+      if(!invert)
+         return -erf_imp(T(-z), invert, pol, t);
+      else if(z < -0.5)
+         return 2 - erf_imp(T(-z), invert, pol, t);
+      else
+         return 1 + erf_imp(T(-z), false, pol, t);
+   }
+
+   T result;
+
+   //
+   // Big bunch of selection statements now to pick which
+   // implementation to use, try to put most likely options
+   // first:
+   //
+   if(z < 0.5)
+   {
+      //
+      // We're going to calculate erf:
+      //
+      if(z == 0)
+      {
+         result = 0;
+      }
+      else if(z < 1e-10)
+      {
+         static const T c = BOOST_MATH_BIG_CONSTANT(T, 64, 0.003379167095512573896158903121545171688);
+         result = z * 1.125 + z * c;
+      }
+      else
+      {
+         // Max Error found at long double precision =   1.623299e-20
+         // Maximum Deviation Found:                     4.326e-22
+         // Expected Error Term:                         -4.326e-22
+         // Maximum Relative Change in Control Points:   1.474e-04
+         static const T Y = 1.044948577880859375f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0834305892146531988966),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.338097283075565413695),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.0509602734406067204596),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.00904906346158537794396),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.000489468651464798669181),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.200305626366151877759e-4),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.455817300515875172439),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0916537354356241792007),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0102722652675910031202),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.000650511752687851548735),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.189532519105655496778e-4),
+         };
+         result = z * (Y + tools::evaluate_polynomial(P, T(z * z)) / tools::evaluate_polynomial(Q, T(z * z)));
+      }
+   }
+   else if(invert ? (z < 110) : (z < 6.4f))
+   {
+      //
+      // We'll be calculating erfc:
+      //
+      invert = !invert;
+      if(z < 1.5)
+      {
+         // Max Error found at long double precision =   3.239590e-20
+         // Maximum Deviation Found:                     2.241e-20
+         // Expected Error Term:                         -2.241e-20
+         // Maximum Relative Change in Control Points:   5.110e-03
+         static const T Y = 0.405935764312744140625f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.0980905922162812031672),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.159989089922969141329),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.222359821619935712378),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.127303921703577362312),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0384057530342762400273),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.00628431160851156719325),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.000441266654514391746428),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.266689068336295642561e-7),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 2.03237474985469469291),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 1.78355454954969405222),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.867940326293760578231),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.248025606990021698392),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0396649631833002269861),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.00279220237309449026796),
+         };
+         result = Y + tools::evaluate_polynomial(P, T(z - 0.5f)) / tools::evaluate_polynomial(Q, T(z - 0.5f));
+         T hi, lo;
+         int expon;
+         hi = floor(ldexp(frexp(z, &expon), 32));
+         hi = ldexp(hi, expon - 32);
+         lo = z - hi;
+         T sq = z * z;
+         T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo;
+         result *= exp(-sq) * exp(-err_sqr) / z;
+      }
+      else if(z < 2.5)
+      {
+         // Max Error found at long double precision =   3.686211e-21
+         // Maximum Deviation Found:                     1.495e-21
+         // Expected Error Term:                         -1.494e-21
+         // Maximum Relative Change in Control Points:   1.793e-04
+         static const T Y = 0.50672817230224609375f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.024350047620769840217),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0343522687935671451309),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0505420824305544949541),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0257479325917757388209),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.00669349844190354356118),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.00090807914416099524444),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.515917266698050027934e-4),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 1.71657861671930336344),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 1.26409634824280366218),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.512371437838969015941),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.120902623051120950935),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0158027197831887485261),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.000897871370778031611439),
+         };
+         result = Y + tools::evaluate_polynomial(P, T(z - 1.5f)) / tools::evaluate_polynomial(Q, T(z - 1.5f));
+         T hi, lo;
+         int expon;
+         hi = floor(ldexp(frexp(z, &expon), 32));
+         hi = ldexp(hi, expon - 32);
+         lo = z - hi;
+         T sq = z * z;
+         T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo;
+         result *= exp(-sq) * exp(-err_sqr) / z;
+      }
+      else if(z < 4.5)
+      {
+         // Maximum Deviation Found:                     1.107e-20
+         // Expected Error Term:                         -1.106e-20
+         // Maximum Relative Change in Control Points:   1.709e-04
+         // Max Error found at long double precision =   1.446908e-20
+         static const T Y  = 0.5405750274658203125f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0029527671653097284033),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0141853245895495604051),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0104959584626432293901),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.00343963795976100077626),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.00059065441194877637899),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.523435380636174008685e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.189896043050331257262e-5),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 1.19352160185285642574),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.603256964363454392857),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.165411142458540585835),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0259729870946203166468),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.00221657568292893699158),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.804149464190309799804e-4),
+         };
+         result = Y + tools::evaluate_polynomial(P, T(z - 3.5f)) / tools::evaluate_polynomial(Q, T(z - 3.5f));
+         T hi, lo;
+         int expon;
+         hi = floor(ldexp(frexp(z, &expon), 32));
+         hi = ldexp(hi, expon - 32);
+         lo = z - hi;
+         T sq = z * z;
+         T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo;
+         result *= exp(-sq) * exp(-err_sqr) / z;
+      }
+      else
+      {
+         // Max Error found at long double precision =   7.961166e-21
+         // Maximum Deviation Found:                     6.677e-21
+         // Expected Error Term:                         6.676e-21
+         // Maximum Relative Change in Control Points:   2.319e-05
+         static const T Y = 0.55825519561767578125f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.00593438793008050214106),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 0.0280666231009089713937),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.141597835204583050043),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -0.978088201154300548842),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -5.47351527796012049443),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -13.8677304660245326627),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -27.1274948720539821722),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -29.2545152747009461519),
+            BOOST_MATH_BIG_CONSTANT(T, 64, -16.8865774499799676937),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 4.72948911186645394541),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 23.6750543147695749212),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 60.0021517335693186785),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 131.766251645149522868),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 178.167924971283482513),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 182.499390505915222699),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 104.365251479578577989),
+            BOOST_MATH_BIG_CONSTANT(T, 64, 30.8365511891224291717),
+         };
+         result = Y + tools::evaluate_polynomial(P, T(1 / z)) / tools::evaluate_polynomial(Q, T(1 / z));
+         T hi, lo;
+         int expon;
+         hi = floor(ldexp(frexp(z, &expon), 32));
+         hi = ldexp(hi, expon - 32);
+         lo = z - hi;
+         T sq = z * z;
+         T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo;
+         result *= exp(-sq) * exp(-err_sqr) / z;
+      }
+   }
+   else
+   {
+      //
+      // Any value of z larger than 110 will underflow to zero:
+      //
+      result = 0;
+      invert = !invert;
+   }
+
+   if(invert)
+   {
+      result = 1 - result;
+   }
+
+   return result;
+} // template <class T, class Lanczos>T erf_imp(T z, bool invert, const Lanczos& l, const boost::integral_constant<int, 64>& t)
+
+
+template <class T, class Policy>
+T erf_imp(T z, bool invert, const Policy& pol, const boost::integral_constant<int, 113>& t)
+{
+   BOOST_MATH_STD_USING
+
+   BOOST_MATH_INSTRUMENT_CODE("113-bit precision erf_imp called");
+
+   if(z < 0)
+   {
+      if(!invert)
+         return -erf_imp(T(-z), invert, pol, t);
+      else if(z < -0.5)
+         return 2 - erf_imp(T(-z), invert, pol, t);
+      else
+         return 1 + erf_imp(T(-z), false, pol, t);
+   }
+
+   T result;
+
+   //
+   // Big bunch of selection statements now to pick which
+   // implementation to use, try to put most likely options
+   // first:
+   //
+   if(z < 0.5)
+   {
+      //
+      // We're going to calculate erf:
+      //
+      if(z == 0)
+      {
+         result = 0;
+      }
+      else if(z < 1e-20)
+      {
+         static const T c = BOOST_MATH_BIG_CONSTANT(T, 113, 0.003379167095512573896158903121545171688);
+         result = z * 1.125 + z * c;
+      }
+      else
+      {
+         // Max Error found at long double precision =   2.342380e-35
+         // Maximum Deviation Found:                     6.124e-36
+         // Expected Error Term:                         -6.124e-36
+         // Maximum Relative Change in Control Points:   3.492e-10
+         static const T Y = 1.0841522216796875f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0442269454158250738961589031215451778),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.35549265736002144875335323556961233),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.0582179564566667896225454670863270393),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.0112694696904802304229950538453123925),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.000805730648981801146251825329609079099),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.566304966591936566229702842075966273e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.169655010425186987820201021510002265e-5),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.344448249920445916714548295433198544e-7),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.466542092785657604666906909196052522),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.100005087012526447295176964142107611),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0128341535890117646540050072234142603),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00107150448466867929159660677016658186),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.586168368028999183607733369248338474e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.196230608502104324965623171516808796e-5),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.313388521582925207734229967907890146e-7),
+         };
+         result = z * (Y + tools::evaluate_polynomial(P, T(z * z)) / tools::evaluate_polynomial(Q, T(z * z)));
+      }
+   }
+   else if(invert ? (z < 110) : (z < 8.65f))
+   {
+      //
+      // We'll be calculating erfc:
+      //
+      invert = !invert;
+      if(z < 1)
+      {
+         // Max Error found at long double precision =   3.246278e-35
+         // Maximum Deviation Found:                     1.388e-35
+         // Expected Error Term:                         1.387e-35
+         // Maximum Relative Change in Control Points:   6.127e-05
+         static const T Y = 0.371877193450927734375f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.0640320213544647969396032886581290455),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.200769874440155895637857443946706731),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.378447199873537170666487408805779826),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.30521399466465939450398642044975127),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.146890026406815277906781824723458196),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0464837937749539978247589252732769567),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00987895759019540115099100165904822903),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00137507575429025512038051025154301132),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0001144764551085935580772512359680516),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.436544865032836914773944382339900079e-5),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 2.47651182872457465043733800302427977),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 2.78706486002517996428836400245547955),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.87295924621659627926365005293130693),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.829375825174365625428280908787261065),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.251334771307848291593780143950311514),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0522110268876176186719436765734722473),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00718332151250963182233267040106902368),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.000595279058621482041084986219276392459),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.226988669466501655990637599399326874e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.270666232259029102353426738909226413e-10),
+         };
+         result = Y + tools::evaluate_polynomial(P, T(z - 0.5f)) / tools::evaluate_polynomial(Q, T(z - 0.5f));
+         T hi, lo;
+         int expon;
+         hi = floor(ldexp(frexp(z, &expon), 56));
+         hi = ldexp(hi, expon - 56);
+         lo = z - hi;
+         T sq = z * z;
+         T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo;
+         result *= exp(-sq) * exp(-err_sqr) / z;
+      }
+      else if(z < 1.5)
+      {
+         // Max Error found at long double precision =   2.215785e-35
+         // Maximum Deviation Found:                     1.539e-35
+         // Expected Error Term:                         1.538e-35
+         // Maximum Relative Change in Control Points:   6.104e-05
+         static const T Y = 0.45658016204833984375f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.0289965858925328393392496555094848345),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0868181194868601184627743162571779226),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.169373435121178901746317404936356745),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.13350446515949251201104889028133486),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0617447837290183627136837688446313313),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0185618495228251406703152962489700468),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00371949406491883508764162050169531013),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.000485121708792921297742105775823900772),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.376494706741453489892108068231400061e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.133166058052466262415271732172490045e-5),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 2.32970330146503867261275580968135126),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 2.46325715420422771961250513514928746),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.55307882560757679068505047390857842),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.644274289865972449441174485441409076),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.182609091063258208068606847453955649),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0354171651271241474946129665801606795),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00454060370165285246451879969534083997),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.000349871943711566546821198612518656486),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.123749319840299552925421880481085392e-4),
+         };
+         result = Y + tools::evaluate_polynomial(P, T(z - 1.0f)) / tools::evaluate_polynomial(Q, T(z - 1.0f));
+         T hi, lo;
+         int expon;
+         hi = floor(ldexp(frexp(z, &expon), 56));
+         hi = ldexp(hi, expon - 56);
+         lo = z - hi;
+         T sq = z * z;
+         T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo;
+         result *= exp(-sq) * exp(-err_sqr) / z;
+      }
+      else if(z < 2.25)
+      {
+         // Maximum Deviation Found:                     1.418e-35
+         // Expected Error Term:                         1.418e-35
+         // Maximum Relative Change in Control Points:   1.316e-04
+         // Max Error found at long double precision =   1.998462e-35
+         static const T Y = 0.50250148773193359375f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.0201233630504573402185161184151016606),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0331864357574860196516686996302305002),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0716562720864787193337475444413405461),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0545835322082103985114927569724880658),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0236692635189696678976549720784989593),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00656970902163248872837262539337601845),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00120282643299089441390490459256235021),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.000142123229065182650020762792081622986),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.991531438367015135346716277792989347e-5),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.312857043762117596999398067153076051e-6),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 2.13506082409097783827103424943508554),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 2.06399257267556230937723190496806215),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.18678481279932541314830499880691109),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.447733186643051752513538142316799562),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.11505680005657879437196953047542148),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.020163993632192726170219663831914034),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00232708971840141388847728782209730585),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.000160733201627963528519726484608224112),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.507158721790721802724402992033269266e-5),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.18647774409821470950544212696270639e-12),
+         };
+         result = Y + tools::evaluate_polynomial(P, T(z - 1.5f)) / tools::evaluate_polynomial(Q, T(z - 1.5f));
+         T hi, lo;
+         int expon;
+         hi = floor(ldexp(frexp(z, &expon), 56));
+         hi = ldexp(hi, expon - 56);
+         lo = z - hi;
+         T sq = z * z;
+         T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo;
+         result *= exp(-sq) * exp(-err_sqr) / z;
+      }
+      else if (z < 3)
+      {
+         // Maximum Deviation Found:                     3.575e-36
+         // Expected Error Term:                         3.575e-36
+         // Maximum Relative Change in Control Points:   7.103e-05
+         // Max Error found at long double precision =   5.794737e-36
+         static const T Y = 0.52896785736083984375f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.00902152521745813634562524098263360074),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0145207142776691539346923710537580927),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0301681239582193983824211995978678571),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0215548540823305814379020678660434461),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00864683476267958365678294164340749949),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00219693096885585491739823283511049902),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.000364961639163319762492184502159894371),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.388174251026723752769264051548703059e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.241918026931789436000532513553594321e-5),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.676586625472423508158937481943649258e-7),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.93669171363907292305550231764920001),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.69468476144051356810672506101377494),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.880023580986436640372794392579985511),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.299099106711315090710836273697708402),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0690593962363545715997445583603382337),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0108427016361318921960863149875360222),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00111747247208044534520499324234317695),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.686843205749767250666787987163701209e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.192093541425429248675532015101904262e-5),
+         };
+         result = Y + tools::evaluate_polynomial(P, T(z - 2.25f)) / tools::evaluate_polynomial(Q, T(z - 2.25f));
+         T hi, lo;
+         int expon;
+         hi = floor(ldexp(frexp(z, &expon), 56));
+         hi = ldexp(hi, expon - 56);
+         lo = z - hi;
+         T sq = z * z;
+         T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo;
+         result *= exp(-sq) * exp(-err_sqr) / z;
+      }
+      else if(z < 3.5)
+      {
+         // Maximum Deviation Found:                     8.126e-37
+         // Expected Error Term:                         -8.126e-37
+         // Maximum Relative Change in Control Points:   1.363e-04
+         // Max Error found at long double precision =   1.747062e-36
+         static const T Y = 0.54037380218505859375f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.0033703486408887424921155540591370375),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0104948043110005245215286678898115811),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0148530118504000311502310457390417795),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00816693029245443090102738825536188916),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00249716579989140882491939681805594585),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0004655591010047353023978045800916647),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.531129557920045295895085236636025323e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.343526765122727069515775194111741049e-5),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.971120407556888763695313774578711839e-7),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.59911256167540354915906501335919317),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.136006830764025173864831382946934),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.468565867990030871678574840738423023),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.122821824954470343413956476900662236),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0209670914950115943338996513330141633),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00227845718243186165620199012883547257),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.000144243326443913171313947613547085553),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.407763415954267700941230249989140046e-5),
+         };
+         result = Y + tools::evaluate_polynomial(P, T(z - 3.0f)) / tools::evaluate_polynomial(Q, T(z - 3.0f));
+         T hi, lo;
+         int expon;
+         hi = floor(ldexp(frexp(z, &expon), 56));
+         hi = ldexp(hi, expon - 56);
+         lo = z - hi;
+         T sq = z * z;
+         T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo;
+         result *= exp(-sq) * exp(-err_sqr) / z;
+      }
+      else if(z < 5.5)
+      {
+         // Maximum Deviation Found:                     5.804e-36
+         // Expected Error Term:                         -5.803e-36
+         // Maximum Relative Change in Control Points:   2.475e-05
+         // Max Error found at long double precision =   1.349545e-35
+         static const T Y = 0.55000019073486328125f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00118142849742309772151454518093813615),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0072201822885703318172366893469382745),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0078782276276860110721875733778481505),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00418229166204362376187593976656261146),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00134198400587769200074194304298642705),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.000283210387078004063264777611497435572),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.405687064094911866569295610914844928e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.39348283801568113807887364414008292e-5),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.248798540917787001526976889284624449e-6),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.929502490223452372919607105387474751e-8),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.156161469668275442569286723236274457e-9),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.52955245103668419479878456656709381),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.06263944820093830054635017117417064),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.441684612681607364321013134378316463),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.121665258426166960049773715928906382),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0232134512374747691424978642874321434),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00310778180686296328582860464875562636),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.000288361770756174705123674838640161693),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.177529187194133944622193191942300132e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.655068544833064069223029299070876623e-6),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.11005507545746069573608988651927452e-7),
+         };
+         result = Y + tools::evaluate_polynomial(P, T(z - 4.5f)) / tools::evaluate_polynomial(Q, T(z - 4.5f));
+         T hi, lo;
+         int expon;
+         hi = floor(ldexp(frexp(z, &expon), 56));
+         hi = ldexp(hi, expon - 56);
+         lo = z - hi;
+         T sq = z * z;
+         T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo;
+         result *= exp(-sq) * exp(-err_sqr) / z;
+      }
+      else if(z < 7.5)
+      {
+         // Maximum Deviation Found:                     1.007e-36
+         // Expected Error Term:                         1.007e-36
+         // Maximum Relative Change in Control Points:   1.027e-03
+         // Max Error found at long double precision =   2.646420e-36
+         static const T Y = 0.5574436187744140625f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.000293236907400849056269309713064107674),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00225110719535060642692275221961480162),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00190984458121502831421717207849429799),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.000747757733460111743833929141001680706),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.000170663175280949889583158597373928096),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.246441188958013822253071608197514058e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.229818000860544644974205957895688106e-5),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.134886977703388748488480980637704864e-6),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.454764611880548962757125070106650958e-8),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.673002744115866600294723141176820155e-10),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.12843690320861239631195353379313367),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.569900657061622955362493442186537259),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.169094404206844928112348730277514273),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0324887449084220415058158657252147063),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00419252877436825753042680842608219552),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00036344133176118603523976748563178578),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.204123895931375107397698245752850347e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.674128352521481412232785122943508729e-6),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.997637501418963696542159244436245077e-8),
+         };
+         result = Y + tools::evaluate_polynomial(P, T(z - 6.5f)) / tools::evaluate_polynomial(Q, T(z - 6.5f));
+         T hi, lo;
+         int expon;
+         hi = floor(ldexp(frexp(z, &expon), 56));
+         hi = ldexp(hi, expon - 56);
+         lo = z - hi;
+         T sq = z * z;
+         T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo;
+         result *= exp(-sq) * exp(-err_sqr) / z;
+      }
+      else if(z < 11.5)
+      {
+         // Maximum Deviation Found:                     8.380e-36
+         // Expected Error Term:                         8.380e-36
+         // Maximum Relative Change in Control Points:   2.632e-06
+         // Max Error found at long double precision =   9.849522e-36
+         static const T Y = 0.56083202362060546875f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.000282420728751494363613829834891390121),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00175387065018002823433704079355125161),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0021344978564889819420775336322920375),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00124151356560137532655039683963075661),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.000423600733566948018555157026862139644),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.914030340865175237133613697319509698e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.126999927156823363353809747017945494e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.110610959842869849776179749369376402e-5),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.55075079477173482096725348704634529e-7),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.119735694018906705225870691331543806e-8),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.69889613396167354566098060039549882),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.28824647372749624464956031163282674),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.572297795434934493541628008224078717),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.164157697425571712377043857240773164),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.0315311145224594430281219516531649562),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00405588922155632380812945849777127458),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.000336929033691445666232029762868642417),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.164033049810404773469413526427932109e-4),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.356615210500531410114914617294694857e-6),
+         };
+         result = Y + tools::evaluate_polynomial(P, T(z / 2 - 4.75f)) / tools::evaluate_polynomial(Q, T(z / 2 - 4.75f));
+         T hi, lo;
+         int expon;
+         hi = floor(ldexp(frexp(z, &expon), 56));
+         hi = ldexp(hi, expon - 56);
+         lo = z - hi;
+         T sq = z * z;
+         T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo;
+         result *= exp(-sq) * exp(-err_sqr) / z;
+      }
+      else
+      {
+         // Maximum Deviation Found:                     1.132e-35
+         // Expected Error Term:                         -1.132e-35
+         // Maximum Relative Change in Control Points:   4.674e-04
+         // Max Error found at long double precision =   1.162590e-35
+         static const T Y = 0.5632686614990234375f;
+         static const T P[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.000920922048732849448079451574171836943),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 0.00321439044532288750501700028748922439),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.250455263029390118657884864261823431),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -0.906807635364090342031792404764598142),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -8.92233572835991735876688745989985565),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -21.7797433494422564811782116907878495),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -91.1451915251976354349734589601171659),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -144.1279109655993927069052125017673),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -313.845076581796338665519022313775589),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -273.11378811923343424081101235736475),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -271.651566205951067025696102600443452),
+            BOOST_MATH_BIG_CONSTANT(T, 113, -60.0530577077238079968843307523245547),
+         };
+         static const T Q[] = {    
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 3.49040448075464744191022350947892036),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 34.3563592467165971295915749548313227),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 84.4993232033879023178285731843850461),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 376.005865281206894120659401340373818),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 629.95369438888946233003926191755125),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1568.35771983533158591604513304269098),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1646.02452040831961063640827116581021),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 2299.96860633240298708910425594484895),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 1222.73204392037452750381340219906374),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 799.359797306084372350264298361110448),
+            BOOST_MATH_BIG_CONSTANT(T, 113, 72.7415265778588087243442792401576737),
+         };
+         result = Y + tools::evaluate_polynomial(P, T(1 / z)) / tools::evaluate_polynomial(Q, T(1 / z));
+         T hi, lo;
+         int expon;
+         hi = floor(ldexp(frexp(z, &expon), 56));
+         hi = ldexp(hi, expon - 56);
+         lo = z - hi;
+         T sq = z * z;
+         T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo;
+         result *= exp(-sq) * exp(-err_sqr) / z;
+      }
+   }
+   else
+   {
+      //
+      // Any value of z larger than 110 will underflow to zero:
+      //
+      result = 0;
+      invert = !invert;
+   }
+
+   if(invert)
+   {
+      result = 1 - result;
+   }
+
+   return result;
+} // template <class T, class Lanczos>T erf_imp(T z, bool invert, const Lanczos& l, const boost::integral_constant<int, 113>& t)
+
+template <class T, class Policy, class tag>
+struct erf_initializer
+{
+   struct init
+   {
+      init()
+      {
+         do_init(tag());
+      }
+      static void do_init(const boost::integral_constant<int, 0>&){}
+      static void do_init(const boost::integral_constant<int, 53>&)
+      {
+         boost::math::erf(static_cast<T>(1e-12), Policy());
+         boost::math::erf(static_cast<T>(0.25), Policy());
+         boost::math::erf(static_cast<T>(1.25), Policy());
+         boost::math::erf(static_cast<T>(2.25), Policy());
+         boost::math::erf(static_cast<T>(4.25), Policy());
+         boost::math::erf(static_cast<T>(5.25), Policy());
+      }
+      static void do_init(const boost::integral_constant<int, 64>&)
+      {
+         boost::math::erf(static_cast<T>(1e-12), Policy());
+         boost::math::erf(static_cast<T>(0.25), Policy());
+         boost::math::erf(static_cast<T>(1.25), Policy());
+         boost::math::erf(static_cast<T>(2.25), Policy());
+         boost::math::erf(static_cast<T>(4.25), Policy());
+         boost::math::erf(static_cast<T>(5.25), Policy());
+      }
+      static void do_init(const boost::integral_constant<int, 113>&)
+      {
+         boost::math::erf(static_cast<T>(1e-22), Policy());
+         boost::math::erf(static_cast<T>(0.25), Policy());
+         boost::math::erf(static_cast<T>(1.25), Policy());
+         boost::math::erf(static_cast<T>(2.125), Policy());
+         boost::math::erf(static_cast<T>(2.75), Policy());
+         boost::math::erf(static_cast<T>(3.25), Policy());
+         boost::math::erf(static_cast<T>(5.25), Policy());
+         boost::math::erf(static_cast<T>(7.25), Policy());
+         boost::math::erf(static_cast<T>(11.25), Policy());
+         boost::math::erf(static_cast<T>(12.5), Policy());
+      }
+      void force_instantiate()const{}
+   };
+   static const init initializer;
+   static void force_instantiate()
+   {
+      initializer.force_instantiate();
+   }
+};
+
+template <class T, class Policy, class tag>
+const typename erf_initializer<T, Policy, tag>::init erf_initializer<T, Policy, tag>::initializer;
+
+} // namespace detail
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type erf(T z, const Policy& /* pol */)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   typedef typename policies::precision<result_type, Policy>::type precision_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   BOOST_MATH_INSTRUMENT_CODE("result_type = " << typeid(result_type).name());
+   BOOST_MATH_INSTRUMENT_CODE("value_type = " << typeid(value_type).name());
+   BOOST_MATH_INSTRUMENT_CODE("precision_type = " << typeid(precision_type).name());
+
+   typedef boost::integral_constant<int,
+      precision_type::value <= 0 ? 0 :
+      precision_type::value <= 53 ? 53 :
+      precision_type::value <= 64 ? 64 :
+      precision_type::value <= 113 ? 113 : 0
+   > tag_type;
+
+   BOOST_MATH_INSTRUMENT_CODE("tag_type = " << typeid(tag_type).name());
+
+   detail::erf_initializer<value_type, forwarding_policy, tag_type>::force_instantiate(); // Force constants to be initialized before main
+
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::erf_imp(
+      static_cast<value_type>(z),
+      false,
+      forwarding_policy(),
+      tag_type()), "boost::math::erf<%1%>(%1%, %1%)");
+}
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type erfc(T z, const Policy& /* pol */)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   typedef typename policies::precision<result_type, Policy>::type precision_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   BOOST_MATH_INSTRUMENT_CODE("result_type = " << typeid(result_type).name());
+   BOOST_MATH_INSTRUMENT_CODE("value_type = " << typeid(value_type).name());
+   BOOST_MATH_INSTRUMENT_CODE("precision_type = " << typeid(precision_type).name());
+
+   typedef boost::integral_constant<int,
+      precision_type::value <= 0 ? 0 :
+      precision_type::value <= 53 ? 53 :
+      precision_type::value <= 64 ? 64 :
+      precision_type::value <= 113 ? 113 : 0
+   > tag_type;
+
+   BOOST_MATH_INSTRUMENT_CODE("tag_type = " << typeid(tag_type).name());
+
+   detail::erf_initializer<value_type, forwarding_policy, tag_type>::force_instantiate(); // Force constants to be initialized before main
+
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::erf_imp(
+      static_cast<value_type>(z),
+      true,
+      forwarding_policy(),
+      tag_type()), "boost::math::erfc<%1%>(%1%, %1%)");
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type erf(T z)
+{
+   return boost::math::erf(z, policies::policy<>());
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type erfc(T z)
+{
+   return boost::math::erfc(z, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#include <boost/math/special_functions/detail/erf_inv.hpp>
+
+#endif // BOOST_MATH_SPECIAL_ERF_HPP
+
+
+
+
diff --git a/ThirdParty/boost/math/special_functions/expm1.hpp b/ThirdParty/boost/math/special_functions/expm1.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..be4e831f118f0eaa277c1b5905df86cbde710255
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/expm1.hpp
@@ -0,0 +1,346 @@
+//  (C) Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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_EXPM1_INCLUDED
+#define BOOST_MATH_EXPM1_INCLUDED
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/config/no_tr1/cmath.hpp>
+#include <math.h> // platform's ::expm1
+#include <boost/limits.hpp>
+#include <boost/math/tools/config.hpp>
+#include <boost/math/tools/series.hpp>
+#include <boost/math/tools/precision.hpp>
+#include <boost/math/tools/big_constant.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/tools/rational.hpp>
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/mpl/less_equal.hpp>
+
+#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+#  include <boost/static_assert.hpp>
+#else
+#  include <boost/assert.hpp>
+#endif
+
+#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128)
+//
+// This is the only way we can avoid
+// warning: non-standard suffix on floating constant [-Wpedantic]
+// when building with -Wall -pedantic.  Neither __extension__
+// nor #pragma diagnostic ignored work :(
+//
+#pragma GCC system_header
+#endif
+
+namespace boost{ namespace math{
+
+namespace detail
+{
+  // Functor expm1_series returns the next term in the Taylor series
+  // x^k / k!
+  // each time that operator() is invoked.
+  //
+  template <class T>
+  struct expm1_series
+  {
+     typedef T result_type;
+
+     expm1_series(T x)
+        : k(0), m_x(x), m_term(1) {}
+
+     T operator()()
+     {
+        ++k;
+        m_term *= m_x;
+        m_term /= k;
+        return m_term;
+     }
+
+     int count()const
+     {
+        return k;
+     }
+
+  private:
+     int k;
+     const T m_x;
+     T m_term;
+     expm1_series(const expm1_series&);
+     expm1_series& operator=(const expm1_series&);
+  };
+
+template <class T, class Policy, class tag>
+struct expm1_initializer
+{
+   struct init
+   {
+      init()
+      {
+         do_init(tag());
+      }
+      template <int N>
+      static void do_init(const boost::integral_constant<int, N>&){}
+      static void do_init(const boost::integral_constant<int, 64>&)
+      {
+         expm1(T(0.5));
+      }
+      static void do_init(const boost::integral_constant<int, 113>&)
+      {
+         expm1(T(0.5));
+      }
+      void force_instantiate()const{}
+   };
+   static const init initializer;
+   static void force_instantiate()
+   {
+      initializer.force_instantiate();
+   }
+};
+
+template <class T, class Policy, class tag>
+const typename expm1_initializer<T, Policy, tag>::init expm1_initializer<T, Policy, tag>::initializer;
+
+//
+// Algorithm expm1 is part of C99, but is not yet provided by many compilers.
+//
+// This version uses a Taylor series expansion for 0.5 > |x| > epsilon.
+//
+template <class T, class Policy>
+T expm1_imp(T x, const boost::integral_constant<int, 0>&, const Policy& pol)
+{
+   BOOST_MATH_STD_USING
+
+   T a = fabs(x);
+   if((boost::math::isnan)(a))
+   {
+      return policies::raise_domain_error<T>("boost::math::expm1<%1%>(%1%)", "expm1 requires a finite argument, but got %1%", a, pol);
+   }
+   if(a > T(0.5f))
+   {
+      if(a >= tools::log_max_value<T>())
+      {
+         if(x > 0)
+            return policies::raise_overflow_error<T>("boost::math::expm1<%1%>(%1%)", 0, pol);
+         return -1;
+      }
+      return exp(x) - T(1);
+   }
+   if(a < tools::epsilon<T>())
+      return x;
+   detail::expm1_series<T> s(x);
+   boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) && !BOOST_WORKAROUND(__EDG_VERSION__, <= 245)
+   T result = tools::sum_series(s, policies::get_epsilon<T, Policy>(), max_iter);
+#else
+   T zero = 0;
+   T result = tools::sum_series(s, policies::get_epsilon<T, Policy>(), max_iter, zero);
+#endif
+   policies::check_series_iterations<T>("boost::math::expm1<%1%>(%1%)", max_iter, pol);
+   return result;
+}
+
+template <class T, class P>
+T expm1_imp(T x, const boost::integral_constant<int, 53>&, const P& pol)
+{
+   BOOST_MATH_STD_USING
+
+   T a = fabs(x);
+   if(a > T(0.5L))
+   {
+      if(a >= tools::log_max_value<T>())
+      {
+         if(x > 0)
+            return policies::raise_overflow_error<T>("boost::math::expm1<%1%>(%1%)", 0, pol);
+         return -1;
+      }
+      return exp(x) - T(1);
+   }
+   if(a < tools::epsilon<T>())
+      return x;
+
+   static const float Y = 0.10281276702880859e1f;
+   static const T n[] = { static_cast<T>(-0.28127670288085937e-1), static_cast<T>(0.51278186299064534e0), static_cast<T>(-0.6310029069350198e-1), static_cast<T>(0.11638457975729296e-1), static_cast<T>(-0.52143390687521003e-3), static_cast<T>(0.21491399776965688e-4) };
+   static const T d[] = { 1, static_cast<T>(-0.45442309511354755e0), static_cast<T>(0.90850389570911714e-1), static_cast<T>(-0.10088963629815502e-1), static_cast<T>(0.63003407478692265e-3), static_cast<T>(-0.17976570003654402e-4) };
+
+   T result = x * Y + x * tools::evaluate_polynomial(n, x) / tools::evaluate_polynomial(d, x);
+   return result;
+}
+
+template <class T, class P>
+T expm1_imp(T x, const boost::integral_constant<int, 64>&, const P& pol)
+{
+   BOOST_MATH_STD_USING
+
+   T a = fabs(x);
+   if(a > T(0.5L))
+   {
+      if(a >= tools::log_max_value<T>())
+      {
+         if(x > 0)
+            return policies::raise_overflow_error<T>("boost::math::expm1<%1%>(%1%)", 0, pol);
+         return -1;
+      }
+      return exp(x) - T(1);
+   }
+   if(a < tools::epsilon<T>())
+      return x;
+
+   static const float Y = 0.10281276702880859375e1f;
+   static const T n[] = { 
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.281276702880859375e-1), 
+       BOOST_MATH_BIG_CONSTANT(T, 64, 0.512980290285154286358e0), 
+       BOOST_MATH_BIG_CONSTANT(T, 64, -0.667758794592881019644e-1),
+       BOOST_MATH_BIG_CONSTANT(T, 64, 0.131432469658444745835e-1),
+       BOOST_MATH_BIG_CONSTANT(T, 64, -0.72303795326880286965e-3),
+       BOOST_MATH_BIG_CONSTANT(T, 64, 0.447441185192951335042e-4),
+       BOOST_MATH_BIG_CONSTANT(T, 64, -0.714539134024984593011e-6)
+   };
+   static const T d[] = { 
+      BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.461477618025562520389e0),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.961237488025708540713e-1),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.116483957658204450739e-1),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.873308008461557544458e-3),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.387922804997682392562e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.807473180049193557294e-6)
+   };
+
+   T result = x * Y + x * tools::evaluate_polynomial(n, x) / tools::evaluate_polynomial(d, x);
+   return result;
+}
+
+template <class T, class P>
+T expm1_imp(T x, const boost::integral_constant<int, 113>&, const P& pol)
+{
+   BOOST_MATH_STD_USING
+
+   T a = fabs(x);
+   if(a > T(0.5L))
+   {
+      if(a >= tools::log_max_value<T>())
+      {
+         if(x > 0)
+            return policies::raise_overflow_error<T>("boost::math::expm1<%1%>(%1%)", 0, pol);
+         return -1;
+      }
+      return exp(x) - T(1);
+   }
+   if(a < tools::epsilon<T>())
+      return x;
+
+   static const float Y = 0.10281276702880859375e1f;
+   static const T n[] = { 
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.28127670288085937499999999999999999854e-1),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.51278156911210477556524452177540792214e0),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.63263178520747096729500254678819588223e-1),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.14703285606874250425508446801230572252e-1),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.8675686051689527802425310407898459386e-3),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.88126359618291165384647080266133492399e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.25963087867706310844432390015463138953e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.14226691087800461778631773363204081194e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.15995603306536496772374181066765665596e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.45261820069007790520447958280473183582e-10)
+   };
+   static const T d[] = { 
+      BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.45441264709074310514348137469214538853e0),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.96827131936192217313133611655555298106e-1),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.12745248725908178612540554584374876219e-1),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.11473613871583259821612766907781095472e-2),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.73704168477258911962046591907690764416e-4),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.34087499397791555759285503797256103259e-5),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.11114024704296196166272091230695179724e-6),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.23987051614110848595909588343223896577e-8),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.29477341859111589208776402638429026517e-10),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.13222065991022301420255904060628100924e-12)
+   };
+
+   T result = x * Y + x * tools::evaluate_polynomial(n, x) / tools::evaluate_polynomial(d, x);
+   return result;
+}
+
+} // namespace detail
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type expm1(T x, const Policy& /* pol */)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   typedef typename policies::precision<result_type, Policy>::type precision_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   typedef boost::integral_constant<int,
+      precision_type::value <= 0 ? 0 :
+      precision_type::value <= 53 ? 53 :
+      precision_type::value <= 64 ? 64 :
+      precision_type::value <= 113 ? 113 : 0
+   > tag_type;
+
+   detail::expm1_initializer<value_type, forwarding_policy, tag_type>::force_instantiate();
+   
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::expm1_imp(
+      static_cast<value_type>(x),
+      tag_type(), forwarding_policy()), "boost::math::expm1<%1%>(%1%)");
+}
+
+#ifdef expm1
+#  ifndef BOOST_HAS_expm1
+#     define BOOST_HAS_expm1
+#  endif
+#  undef expm1
+#endif
+
+#if defined(BOOST_HAS_EXPM1) && !(defined(__osf__) && defined(__DECCXX_VER))
+#  ifdef BOOST_MATH_USE_C99
+inline float expm1(float x, const policies::policy<>&){ return ::expm1f(x); }
+#     ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+inline long double expm1(long double x, const policies::policy<>&){ return ::expm1l(x); }
+#     endif
+#  else
+inline float expm1(float x, const policies::policy<>&){ return static_cast<float>(::expm1(x)); }
+#  endif
+inline double expm1(double x, const policies::policy<>&){ return ::expm1(x); }
+#endif
+
+template <class T>
+inline typename tools::promote_args<T>::type expm1(T x)
+{
+   return expm1(x, policies::policy<>());
+}
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+inline float expm1(float z)
+{
+   return expm1<float>(z);
+}
+inline double expm1(double z)
+{
+   return expm1<double>(z);
+}
+#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+inline long double expm1(long double z)
+{
+   return expm1<long double>(z);
+}
+#endif
+#endif
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_HYPOT_INCLUDED
+
+
+
+
diff --git a/ThirdParty/boost/math/special_functions/factorials.hpp b/ThirdParty/boost/math/special_functions/factorials.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..83bdc7a52b1f69e7b73dd8c483040202f4353576
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/factorials.hpp
@@ -0,0 +1,268 @@
+//  Copyright John Maddock 2006, 2010.
+//  Use, modification and distribution are subject to 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_SP_FACTORIALS_HPP
+#define BOOST_MATH_SP_FACTORIALS_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/special_functions/gamma.hpp>
+#include <boost/math/special_functions/detail/unchecked_factorial.hpp>
+#include <boost/array.hpp>
+#ifdef BOOST_MSVC
+#pragma warning(push) // Temporary until lexical cast fixed.
+#pragma warning(disable: 4127 4701)
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+#include <boost/config/no_tr1/cmath.hpp>
+
+namespace boost { namespace math
+{
+
+template <class T, class Policy>
+inline T factorial(unsigned i, const Policy& pol)
+{
+   BOOST_STATIC_ASSERT(!boost::is_integral<T>::value);
+   // factorial<unsigned int>(n) is not implemented
+   // because it would overflow integral type T for too small n
+   // to be useful. Use instead a floating-point type,
+   // and convert to an unsigned type if essential, for example:
+   // unsigned int nfac = static_cast<unsigned int>(factorial<double>(n));
+   // See factorial documentation for more detail.
+
+   BOOST_MATH_STD_USING // Aid ADL for floor.
+
+   if(i <= max_factorial<T>::value)
+      return unchecked_factorial<T>(i);
+   T result = boost::math::tgamma(static_cast<T>(i+1), pol);
+   if(result > tools::max_value<T>())
+      return result; // Overflowed value! (But tgamma will have signalled the error already).
+   return floor(result + 0.5f);
+}
+
+template <class T>
+inline T factorial(unsigned i)
+{
+   return factorial<T>(i, policies::policy<>());
+}
+/*
+// Can't have these in a policy enabled world?
+template<>
+inline float factorial<float>(unsigned i)
+{
+   if(i <= max_factorial<float>::value)
+      return unchecked_factorial<float>(i);
+   return tools::overflow_error<float>(BOOST_CURRENT_FUNCTION);
+}
+
+template<>
+inline double factorial<double>(unsigned i)
+{
+   if(i <= max_factorial<double>::value)
+      return unchecked_factorial<double>(i);
+   return tools::overflow_error<double>(BOOST_CURRENT_FUNCTION);
+}
+*/
+template <class T, class Policy>
+T double_factorial(unsigned i, const Policy& pol)
+{
+   BOOST_STATIC_ASSERT(!boost::is_integral<T>::value);
+   BOOST_MATH_STD_USING  // ADL lookup of std names
+   if(i & 1)
+   {
+      // odd i:
+      if(i < max_factorial<T>::value)
+      {
+         unsigned n = (i - 1) / 2;
+         return ceil(unchecked_factorial<T>(i) / (ldexp(T(1), (int)n) * unchecked_factorial<T>(n)) - 0.5f);
+      }
+      //
+      // Fallthrough: i is too large to use table lookup, try the
+      // gamma function instead.
+      //
+      T result = boost::math::tgamma(static_cast<T>(i) / 2 + 1, pol) / sqrt(constants::pi<T>());
+      if(ldexp(tools::max_value<T>(), -static_cast<int>(i+1) / 2) > result)
+         return ceil(result * ldexp(T(1), static_cast<int>(i+1) / 2) - 0.5f);
+   }
+   else
+   {
+      // even i:
+      unsigned n = i / 2;
+      T result = factorial<T>(n, pol);
+      if(ldexp(tools::max_value<T>(), -(int)n) > result)
+         return result * ldexp(T(1), (int)n);
+   }
+   //
+   // If we fall through to here then the result is infinite:
+   //
+   return policies::raise_overflow_error<T>("boost::math::double_factorial<%1%>(unsigned)", 0, pol);
+}
+
+template <class T>
+inline T double_factorial(unsigned i)
+{
+   return double_factorial<T>(i, policies::policy<>());
+}
+
+namespace detail{
+
+template <class T, class Policy>
+T rising_factorial_imp(T x, int n, const Policy& pol)
+{
+   BOOST_STATIC_ASSERT(!boost::is_integral<T>::value);
+   if(x < 0)
+   {
+      //
+      // For x less than zero, we really have a falling
+      // factorial, modulo a possible change of sign.
+      //
+      // Note that the falling factorial isn't defined
+      // for negative n, so we'll get rid of that case
+      // first:
+      //
+      bool inv = false;
+      if(n < 0)
+      {
+         x += n;
+         n = -n;
+         inv = true;
+      }
+      T result = ((n&1) ? -1 : 1) * falling_factorial(-x, n, pol);
+      if(inv)
+         result = 1 / result;
+      return result;
+   }
+   if(n == 0)
+      return 1;
+   if(x == 0)
+   {
+      if(n < 0)
+         return -boost::math::tgamma_delta_ratio(x + 1, static_cast<T>(-n), pol);
+      else
+         return 0;
+   }
+   if((x < 1) && (x + n < 0))
+   {
+      T val = boost::math::tgamma_delta_ratio(1 - x, static_cast<T>(-n), pol);
+      return (n & 1) ? T(-val) : val;
+   }
+   //
+   // We don't optimise this for small n, because
+   // tgamma_delta_ratio is already optimised for that
+   // use case:
+   //
+   return 1 / boost::math::tgamma_delta_ratio(x, static_cast<T>(n), pol);
+}
+
+template <class T, class Policy>
+inline T falling_factorial_imp(T x, unsigned n, const Policy& pol)
+{
+   BOOST_STATIC_ASSERT(!boost::is_integral<T>::value);
+   BOOST_MATH_STD_USING // ADL of std names
+   if(x == 0)
+      return 0;
+   if(x < 0)
+   {
+      //
+      // For x < 0 we really have a rising factorial
+      // modulo a possible change of sign:
+      //
+      return (n&1 ? -1 : 1) * rising_factorial(-x, n, pol);
+   }
+   if(n == 0)
+      return 1;
+   if(x < 0.5f)
+   {
+      //
+      // 1 + x below will throw away digits, so split up calculation:
+      //
+      if(n > max_factorial<T>::value - 2)
+      {
+         // If the two end of the range are far apart we have a ratio of two very large
+         // numbers, split the calculation up into two blocks:
+         T t1 = x * boost::math::falling_factorial(x - 1, max_factorial<T>::value - 2);
+         T t2 = boost::math::falling_factorial(x - max_factorial<T>::value + 1, n - max_factorial<T>::value + 1);
+         if(tools::max_value<T>() / fabs(t1) < fabs(t2))
+            return boost::math::sign(t1) * boost::math::sign(t2) * policies::raise_overflow_error<T>("boost::math::falling_factorial<%1%>", 0, pol);
+         return t1 * t2;
+      }
+      return x * boost::math::falling_factorial(x - 1, n - 1);
+   }
+   if(x <= n - 1)
+   {
+      //
+      // x+1-n will be negative and tgamma_delta_ratio won't
+      // handle it, split the product up into three parts:
+      //
+      T xp1 = x + 1;
+      unsigned n2 = itrunc((T)floor(xp1), pol);
+      if(n2 == xp1)
+         return 0;
+      T result = boost::math::tgamma_delta_ratio(xp1, -static_cast<T>(n2), pol);
+      x -= n2;
+      result *= x;
+      ++n2;
+      if(n2 < n)
+         result *= falling_factorial(x - 1, n - n2, pol);
+      return result;
+   }
+   //
+   // Simple case: just the ratio of two
+   // (positive argument) gamma functions.
+   // Note that we don't optimise this for small n,
+   // because tgamma_delta_ratio is already optimised
+   // for that use case:
+   //
+   return boost::math::tgamma_delta_ratio(x + 1, -static_cast<T>(n), pol);
+}
+
+} // namespace detail
+
+template <class RT>
+inline typename tools::promote_args<RT>::type
+   falling_factorial(RT x, unsigned n)
+{
+   typedef typename tools::promote_args<RT>::type result_type;
+   return detail::falling_factorial_imp(
+      static_cast<result_type>(x), n, policies::policy<>());
+}
+
+template <class RT, class Policy>
+inline typename tools::promote_args<RT>::type
+   falling_factorial(RT x, unsigned n, const Policy& pol)
+{
+   typedef typename tools::promote_args<RT>::type result_type;
+   return detail::falling_factorial_imp(
+      static_cast<result_type>(x), n, pol);
+}
+
+template <class RT>
+inline typename tools::promote_args<RT>::type
+   rising_factorial(RT x, int n)
+{
+   typedef typename tools::promote_args<RT>::type result_type;
+   return detail::rising_factorial_imp(
+      static_cast<result_type>(x), n, policies::policy<>());
+}
+
+template <class RT, class Policy>
+inline typename tools::promote_args<RT>::type
+   rising_factorial(RT x, int n, const Policy& pol)
+{
+   typedef typename tools::promote_args<RT>::type result_type;
+   return detail::rising_factorial_imp(
+      static_cast<result_type>(x), n, pol);
+}
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_SP_FACTORIALS_HPP
+
diff --git a/ThirdParty/boost/math/special_functions/gamma.hpp b/ThirdParty/boost/math/special_functions/gamma.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e863b42832efb1600a5ab67fb34d557fe7720301
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/gamma.hpp
@@ -0,0 +1,2179 @@
+
+//  Copyright John Maddock 2006-7, 2013-14.
+//  Copyright Paul A. Bristow 2007, 2013-14.
+//  Copyright Nikhar Agrawal 2013-14
+//  Copyright Christopher Kormanyos 2013-14
+
+//  Use, modification and distribution are subject to 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_SF_GAMMA_HPP
+#define BOOST_MATH_SF_GAMMA_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/config.hpp>
+#include <boost/math/tools/series.hpp>
+#include <boost/math/tools/fraction.hpp>
+#include <boost/math/tools/precision.hpp>
+#include <boost/math/tools/promotion.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/constants/constants.hpp>
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/special_functions/log1p.hpp>
+#include <boost/math/special_functions/trunc.hpp>
+#include <boost/math/special_functions/powm1.hpp>
+#include <boost/math/special_functions/sqrt1pm1.hpp>
+#include <boost/math/special_functions/lanczos.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
+#include <boost/math/special_functions/detail/igamma_large.hpp>
+#include <boost/math/special_functions/detail/unchecked_factorial.hpp>
+#include <boost/math/special_functions/detail/lgamma_small.hpp>
+#include <boost/math/special_functions/bernoulli.hpp>
+#include <boost/math/special_functions/polygamma.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/assert.hpp>
+#include <boost/mpl/greater.hpp>
+#include <boost/mpl/equal_to.hpp>
+#include <boost/mpl/greater.hpp>
+
+#include <boost/config/no_tr1/cmath.hpp>
+#include <algorithm>
+
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable: 4702) // unreachable code (return after domain_error throw).
+# pragma warning(disable: 4127) // conditional expression is constant.
+# pragma warning(disable: 4100) // unreferenced formal parameter.
+// Several variables made comments,
+// but some difficulty as whether referenced on not may depend on macro values.
+// So to be safe, 4100 warnings suppressed.
+// TODO - revisit this?
+#endif
+
+namespace boost{ namespace math{
+
+namespace detail{
+
+template <class T>
+inline bool is_odd(T v, const boost::true_type&)
+{
+   int i = static_cast<int>(v);
+   return i&1;
+}
+template <class T>
+inline bool is_odd(T v, const boost::false_type&)
+{
+   // Oh dear can't cast T to int!
+   BOOST_MATH_STD_USING
+   T modulus = v - 2 * floor(v/2);
+   return static_cast<bool>(modulus != 0);
+}
+template <class T>
+inline bool is_odd(T v)
+{
+   return is_odd(v, ::boost::is_convertible<T, int>());
+}
+
+template <class T>
+T sinpx(T z)
+{
+   // Ad hoc function calculates x * sin(pi * x),
+   // taking extra care near when x is near a whole number.
+   BOOST_MATH_STD_USING
+   int sign = 1;
+   if(z < 0)
+   {
+      z = -z;
+   }
+   T fl = floor(z);
+   T dist;
+   if(is_odd(fl))
+   {
+      fl += 1;
+      dist = fl - z;
+      sign = -sign;
+   }
+   else
+   {
+      dist = z - fl;
+   }
+   BOOST_ASSERT(fl >= 0);
+   if(dist > 0.5)
+      dist = 1 - dist;
+   T result = sin(dist*boost::math::constants::pi<T>());
+   return sign*z*result;
+} // template <class T> T sinpx(T z)
+//
+// tgamma(z), with Lanczos support:
+//
+template <class T, class Policy, class Lanczos>
+T gamma_imp(T z, const Policy& pol, const Lanczos& l)
+{
+   BOOST_MATH_STD_USING
+
+   T result = 1;
+
+#ifdef BOOST_MATH_INSTRUMENT
+   static bool b = false;
+   if(!b)
+   {
+      std::cout << "tgamma_imp called with " << typeid(z).name() << " " << typeid(l).name() << std::endl;
+      b = true;
+   }
+#endif
+   static const char* function = "boost::math::tgamma<%1%>(%1%)";
+
+   if(z <= 0)
+   {
+      if(floor(z) == z)
+         return policies::raise_pole_error<T>(function, "Evaluation of tgamma at a negative integer %1%.", z, pol);
+      if(z <= -20)
+      {
+         result = gamma_imp(T(-z), pol, l) * sinpx(z);
+         BOOST_MATH_INSTRUMENT_VARIABLE(result);
+         if((fabs(result) < 1) && (tools::max_value<T>() * fabs(result) < boost::math::constants::pi<T>()))
+            return -boost::math::sign(result) * policies::raise_overflow_error<T>(function, "Result of tgamma is too large to represent.", pol);
+         result = -boost::math::constants::pi<T>() / result;
+         if(result == 0)
+            return policies::raise_underflow_error<T>(function, "Result of tgamma is too small to represent.", pol);
+         if((boost::math::fpclassify)(result) == (int)FP_SUBNORMAL)
+            return policies::raise_denorm_error<T>(function, "Result of tgamma is denormalized.", result, pol);
+         BOOST_MATH_INSTRUMENT_VARIABLE(result);
+         return result;
+      }
+
+      // shift z to > 1:
+      while(z < 0)
+      {
+         result /= z;
+         z += 1;
+      }
+   }
+   BOOST_MATH_INSTRUMENT_VARIABLE(result);
+   if((floor(z) == z) && (z < max_factorial<T>::value))
+   {
+      result *= unchecked_factorial<T>(itrunc(z, pol) - 1);
+      BOOST_MATH_INSTRUMENT_VARIABLE(result);
+   }
+   else if (z < tools::root_epsilon<T>())
+   {
+      if (z < 1 / tools::max_value<T>())
+         result = policies::raise_overflow_error<T>(function, 0, pol);
+      result *= 1 / z - constants::euler<T>();
+   }
+   else
+   {
+      result *= Lanczos::lanczos_sum(z);
+      T zgh = (z + static_cast<T>(Lanczos::g()) - boost::math::constants::half<T>());
+      T lzgh = log(zgh);
+      BOOST_MATH_INSTRUMENT_VARIABLE(result);
+      BOOST_MATH_INSTRUMENT_VARIABLE(tools::log_max_value<T>());
+      if(z * lzgh > tools::log_max_value<T>())
+      {
+         // we're going to overflow unless this is done with care:
+         BOOST_MATH_INSTRUMENT_VARIABLE(zgh);
+         if(lzgh * z / 2 > tools::log_max_value<T>())
+            return boost::math::sign(result) * policies::raise_overflow_error<T>(function, "Result of tgamma is too large to represent.", pol);
+         T hp = pow(zgh, (z / 2) - T(0.25));
+         BOOST_MATH_INSTRUMENT_VARIABLE(hp);
+         result *= hp / exp(zgh);
+         BOOST_MATH_INSTRUMENT_VARIABLE(result);
+         if(tools::max_value<T>() / hp < result)
+            return boost::math::sign(result) * policies::raise_overflow_error<T>(function, "Result of tgamma is too large to represent.", pol);
+         result *= hp;
+         BOOST_MATH_INSTRUMENT_VARIABLE(result);
+      }
+      else
+      {
+         BOOST_MATH_INSTRUMENT_VARIABLE(zgh);
+         BOOST_MATH_INSTRUMENT_VARIABLE(pow(zgh, z - boost::math::constants::half<T>()));
+         BOOST_MATH_INSTRUMENT_VARIABLE(exp(zgh));
+         result *= pow(zgh, z - boost::math::constants::half<T>()) / exp(zgh);
+         BOOST_MATH_INSTRUMENT_VARIABLE(result);
+      }
+   }
+   return result;
+}
+//
+// lgamma(z) with Lanczos support:
+//
+template <class T, class Policy, class Lanczos>
+T lgamma_imp(T z, const Policy& pol, const Lanczos& l, int* sign = 0)
+{
+#ifdef BOOST_MATH_INSTRUMENT
+   static bool b = false;
+   if(!b)
+   {
+      std::cout << "lgamma_imp called with " << typeid(z).name() << " " << typeid(l).name() << std::endl;
+      b = true;
+   }
+#endif
+
+   BOOST_MATH_STD_USING
+
+   static const char* function = "boost::math::lgamma<%1%>(%1%)";
+
+   T result = 0;
+   int sresult = 1;
+   if(z <= -tools::root_epsilon<T>())
+   {
+      // reflection formula:
+      if(floor(z) == z)
+         return policies::raise_pole_error<T>(function, "Evaluation of lgamma at a negative integer %1%.", z, pol);
+
+      T t = sinpx(z);
+      z = -z;
+      if(t < 0)
+      {
+         t = -t;
+      }
+      else
+      {
+         sresult = -sresult;
+      }
+      result = log(boost::math::constants::pi<T>()) - lgamma_imp(z, pol, l) - log(t);
+   }
+   else if (z < tools::root_epsilon<T>())
+   {
+      if (0 == z)
+         return policies::raise_pole_error<T>(function, "Evaluation of lgamma at %1%.", z, pol);
+      if (fabs(z) < 1 / tools::max_value<T>())
+         result = -log(fabs(z));
+      else
+         result = log(fabs(1 / z - constants::euler<T>()));
+      if (z < 0)
+         sresult = -1;
+   }
+   else if(z < 15)
+   {
+      typedef typename policies::precision<T, Policy>::type precision_type;
+      typedef boost::integral_constant<int,
+         precision_type::value <= 0 ? 0 :
+         precision_type::value <= 64 ? 64 :
+         precision_type::value <= 113 ? 113 : 0
+      > tag_type;
+
+      result = lgamma_small_imp<T>(z, T(z - 1), T(z - 2), tag_type(), pol, l);
+   }
+   else if((z >= 3) && (z < 100) && (std::numeric_limits<T>::max_exponent >= 1024))
+   {
+      // taking the log of tgamma reduces the error, no danger of overflow here:
+      result = log(gamma_imp(z, pol, l));
+   }
+   else
+   {
+      // regular evaluation:
+      T zgh = static_cast<T>(z + Lanczos::g() - boost::math::constants::half<T>());
+      result = log(zgh) - 1;
+      result *= z - 0.5f;
+      //
+      // Only add on the lanczos sum part if we're going to need it:
+      //
+      if(result * tools::epsilon<T>() < 20)
+         result += log(Lanczos::lanczos_sum_expG_scaled(z));
+   }
+
+   if(sign)
+      *sign = sresult;
+   return result;
+}
+
+//
+// Incomplete gamma functions follow:
+//
+template <class T>
+struct upper_incomplete_gamma_fract
+{
+private:
+   T z, a;
+   int k;
+public:
+   typedef std::pair<T,T> result_type;
+
+   upper_incomplete_gamma_fract(T a1, T z1)
+      : z(z1-a1+1), a(a1), k(0)
+   {
+   }
+
+   result_type operator()()
+   {
+      ++k;
+      z += 2;
+      return result_type(k * (a - k), z);
+   }
+};
+
+template <class T>
+inline T upper_gamma_fraction(T a, T z, T eps)
+{
+   // Multiply result by z^a * e^-z to get the full
+   // upper incomplete integral.  Divide by tgamma(z)
+   // to normalise.
+   upper_incomplete_gamma_fract<T> f(a, z);
+   return 1 / (z - a + 1 + boost::math::tools::continued_fraction_a(f, eps));
+}
+
+template <class T>
+struct lower_incomplete_gamma_series
+{
+private:
+   T a, z, result;
+public:
+   typedef T result_type;
+   lower_incomplete_gamma_series(T a1, T z1) : a(a1), z(z1), result(1){}
+
+   T operator()()
+   {
+      T r = result;
+      a += 1;
+      result *= z/a;
+      return r;
+   }
+};
+
+template <class T, class Policy>
+inline T lower_gamma_series(T a, T z, const Policy& pol, T init_value = 0)
+{
+   // Multiply result by ((z^a) * (e^-z) / a) to get the full
+   // lower incomplete integral. Then divide by tgamma(a)
+   // to get the normalised value.
+   lower_incomplete_gamma_series<T> s(a, z);
+   boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
+   T factor = policies::get_epsilon<T, Policy>();
+   T result = boost::math::tools::sum_series(s, factor, max_iter, init_value);
+   policies::check_series_iterations<T>("boost::math::detail::lower_gamma_series<%1%>(%1%)", max_iter, pol);
+   return result;
+}
+
+//
+// Fully generic tgamma and lgamma use Stirling's approximation
+// with Bernoulli numbers.
+//
+template<class T>
+std::size_t highest_bernoulli_index()
+{
+   const float digits10_of_type = (std::numeric_limits<T>::is_specialized
+                                      ? static_cast<float>(std::numeric_limits<T>::digits10)
+                                      : static_cast<float>(boost::math::tools::digits<T>() * 0.301F));
+
+   // Find the high index n for Bn to produce the desired precision in Stirling's calculation.
+   return static_cast<std::size_t>(18.0F + (0.6F * digits10_of_type));
+}
+
+template<class T>
+int minimum_argument_for_bernoulli_recursion()
+{
+   const float digits10_of_type = (std::numeric_limits<T>::is_specialized
+                                      ? static_cast<float>(std::numeric_limits<T>::digits10)
+                                      : static_cast<float>(boost::math::tools::digits<T>() * 0.301F));
+
+   const float limit = std::ceil(std::pow(1.0f / std::ldexp(1.0f, 1-boost::math::tools::digits<T>()), 1.0f / 20.0f));
+
+   return (int)((std::min)(digits10_of_type * 1.7F, limit));
+}
+
+template <class T, class Policy>
+T scaled_tgamma_no_lanczos(const T& z, const Policy& pol, bool islog = false)
+{
+   BOOST_MATH_STD_USING
+   //
+   // Calculates tgamma(z) / (z/e)^z
+   // Requires that our argument is large enough for Sterling's approximation to hold.
+   // Used internally when combining gamma's of similar magnitude without logarithms.
+   //
+   BOOST_ASSERT(minimum_argument_for_bernoulli_recursion<T>() <= z);
+
+   // Perform the Bernoulli series expansion of Stirling's approximation.
+
+   const std::size_t number_of_bernoullis_b2n = policies::get_max_series_iterations<Policy>();
+
+   T one_over_x_pow_two_n_minus_one = 1 / z;
+   const T one_over_x2 = one_over_x_pow_two_n_minus_one * one_over_x_pow_two_n_minus_one;
+   T sum = (boost::math::bernoulli_b2n<T>(1) / 2) * one_over_x_pow_two_n_minus_one;
+   const T target_epsilon_to_break_loop = sum * boost::math::tools::epsilon<T>();
+   const T half_ln_two_pi_over_z = sqrt(boost::math::constants::two_pi<T>() / z);
+   T last_term = 2 * sum;
+
+   for (std::size_t n = 2U;; ++n)
+   {
+      one_over_x_pow_two_n_minus_one *= one_over_x2;
+
+      const std::size_t n2 = static_cast<std::size_t>(n * 2U);
+
+      const T term = (boost::math::bernoulli_b2n<T>(static_cast<int>(n)) * one_over_x_pow_two_n_minus_one) / (n2 * (n2 - 1U));
+
+      if ((n >= 3U) && (abs(term) < target_epsilon_to_break_loop))
+      {
+         // We have reached the desired precision in Stirling's expansion.
+         // Adding additional terms to the sum of this divergent asymptotic
+         // expansion will not improve the result.
+
+         // Break from the loop.
+         break;
+      }
+      if (n > number_of_bernoullis_b2n)
+         return policies::raise_evaluation_error("scaled_tgamma_no_lanczos<%1%>()", "Exceeded maximum series iterations without reaching convergence, best approximation was %1%", T(exp(sum) * half_ln_two_pi_over_z), pol);
+
+      sum += term;
+
+      // Sanity check for divergence:
+      T fterm = fabs(term);
+      if(fterm > last_term)
+         return policies::raise_evaluation_error("scaled_tgamma_no_lanczos<%1%>()", "Series became divergent without reaching convergence, best approximation was %1%", T(exp(sum) * half_ln_two_pi_over_z), pol);
+      last_term = fterm;
+   }
+
+   // Complete Stirling's approximation.
+   T scaled_gamma_value = islog ? T(sum + log(half_ln_two_pi_over_z)) : T(exp(sum) * half_ln_two_pi_over_z);
+   return scaled_gamma_value;
+}
+
+// Forward declaration of the lgamma_imp template specialization.
+template <class T, class Policy>
+T lgamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos&, int* sign = 0);
+
+template <class T, class Policy>
+T gamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos&)
+{
+   BOOST_MATH_STD_USING
+
+   static const char* function = "boost::math::tgamma<%1%>(%1%)";
+
+   // Check if the argument of tgamma is identically zero.
+   const bool is_at_zero = (z == 0);
+
+   if((boost::math::isnan)(z) || (is_at_zero) || ((boost::math::isinf)(z) && (z < 0)))
+      return policies::raise_domain_error<T>(function, "Evaluation of tgamma at %1%.", z, pol);
+
+   const bool b_neg = (z < 0);
+
+   const bool floor_of_z_is_equal_to_z = (floor(z) == z);
+
+   // Special case handling of small factorials:
+   if((!b_neg) && floor_of_z_is_equal_to_z && (z < boost::math::max_factorial<T>::value))
+   {
+      return boost::math::unchecked_factorial<T>(itrunc(z) - 1);
+   }
+
+   // Make a local, unsigned copy of the input argument.
+   T zz((!b_neg) ? z : -z);
+
+   // Special case for ultra-small z:
+   if(zz < tools::cbrt_epsilon<T>())
+   {
+      const T a0(1);
+      const T a1(boost::math::constants::euler<T>());
+      const T six_euler_squared((boost::math::constants::euler<T>() * boost::math::constants::euler<T>()) * 6);
+      const T a2((six_euler_squared -  boost::math::constants::pi_sqr<T>()) / 12);
+
+      const T inverse_tgamma_series = z * ((a2 * z + a1) * z + a0);
+
+      return 1 / inverse_tgamma_series;
+   }
+
+   // Scale the argument up for the calculation of lgamma,
+   // and use downward recursion later for the final result.
+   const int min_arg_for_recursion = minimum_argument_for_bernoulli_recursion<T>();
+
+   int n_recur;
+
+   if(zz < min_arg_for_recursion)
+   {
+      n_recur = boost::math::itrunc(min_arg_for_recursion - zz) + 1;
+
+      zz += n_recur;
+   }
+   else
+   {
+      n_recur = 0;
+   }
+   if (!n_recur)
+   {
+      if (zz > tools::log_max_value<T>())
+         return policies::raise_overflow_error<T>(function, 0, pol);
+      if (log(zz) * zz / 2 > tools::log_max_value<T>())
+         return policies::raise_overflow_error<T>(function, 0, pol);
+   }
+   T gamma_value = scaled_tgamma_no_lanczos(zz, pol);
+   T power_term = pow(zz, zz / 2);
+   T exp_term = exp(-zz);
+   gamma_value *= (power_term * exp_term);
+   if(!n_recur && (tools::max_value<T>() / power_term < gamma_value))
+      return policies::raise_overflow_error<T>(function, 0, pol);
+   gamma_value *= power_term;
+
+   // Rescale the result using downward recursion if necessary.
+   if(n_recur)
+   {
+      // The order of divides is important, if we keep subtracting 1 from zz
+      // we DO NOT get back to z (cancellation error).  Further if z < epsilon
+      // we would end up dividing by zero.  Also in order to prevent spurious
+      // overflow with the first division, we must save dividing by |z| till last,
+      // so the optimal order of divides is z+1, z+2, z+3...z+n_recur-1,z.
+      zz = fabs(z) + 1;
+      for(int k = 1; k < n_recur; ++k)
+      {
+         gamma_value /= zz;
+         zz += 1;
+      }
+      gamma_value /= fabs(z);
+   }
+
+   // Return the result, accounting for possible negative arguments.
+   if(b_neg)
+   {
+      // Provide special error analysis for:
+      // * arguments in the neighborhood of a negative integer
+      // * arguments exactly equal to a negative integer.
+
+      // Check if the argument of tgamma is exactly equal to a negative integer.
+      if(floor_of_z_is_equal_to_z)
+         return policies::raise_pole_error<T>(function, "Evaluation of tgamma at a negative integer %1%.", z, pol);
+
+      gamma_value *= sinpx(z);
+
+      BOOST_MATH_INSTRUMENT_VARIABLE(gamma_value);
+
+      const bool result_is_too_large_to_represent = (   (abs(gamma_value) < 1)
+                                                     && ((tools::max_value<T>() * abs(gamma_value)) < boost::math::constants::pi<T>()));
+
+      if(result_is_too_large_to_represent)
+         return policies::raise_overflow_error<T>(function, "Result of tgamma is too large to represent.", pol);
+
+      gamma_value = -boost::math::constants::pi<T>() / gamma_value;
+      BOOST_MATH_INSTRUMENT_VARIABLE(gamma_value);
+
+      if(gamma_value == 0)
+         return policies::raise_underflow_error<T>(function, "Result of tgamma is too small to represent.", pol);
+
+      if((boost::math::fpclassify)(gamma_value) == static_cast<int>(FP_SUBNORMAL))
+         return policies::raise_denorm_error<T>(function, "Result of tgamma is denormalized.", gamma_value, pol);
+   }
+
+   return gamma_value;
+}
+
+template <class T, class Policy>
+inline T log_gamma_near_1(const T& z, Policy const& pol)
+{
+   //
+   // This is for the multiprecision case where there is
+   // no lanczos support, use a taylor series at z = 1,
+   // see https://www.wolframalpha.com/input/?i=taylor+series+lgamma(x)+at+x+%3D+1
+   //
+   BOOST_MATH_STD_USING // ADL of std names
+
+   BOOST_ASSERT(fabs(z) < 1);
+
+   T result = -constants::euler<T>() * z;
+
+   T power_term = z * z / 2;
+   int n = 2;
+   T term = 0;
+
+   do
+   {
+      term = power_term * boost::math::polygamma(n - 1, T(1));
+      result += term;
+      ++n;
+      power_term *= z / n;
+   } while (fabs(result) * tools::epsilon<T>() < fabs(term));
+
+   return result;
+}
+
+template <class T, class Policy>
+T lgamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos&, int* sign)
+{
+   BOOST_MATH_STD_USING
+
+   static const char* function = "boost::math::lgamma<%1%>(%1%)";
+
+   // Check if the argument of lgamma is identically zero.
+   const bool is_at_zero = (z == 0);
+
+   if(is_at_zero)
+      return policies::raise_domain_error<T>(function, "Evaluation of lgamma at zero %1%.", z, pol);
+   if((boost::math::isnan)(z))
+      return policies::raise_domain_error<T>(function, "Evaluation of lgamma at %1%.", z, pol);
+   if((boost::math::isinf)(z))
+      return policies::raise_overflow_error<T>(function, 0, pol);
+
+   const bool b_neg = (z < 0);
+
+   const bool floor_of_z_is_equal_to_z = (floor(z) == z);
+
+   // Special case handling of small factorials:
+   if((!b_neg) && floor_of_z_is_equal_to_z && (z < boost::math::max_factorial<T>::value))
+   {
+      if (sign)
+         *sign = 1;
+      return log(boost::math::unchecked_factorial<T>(itrunc(z) - 1));
+   }
+
+   // Make a local, unsigned copy of the input argument.
+   T zz((!b_neg) ? z : -z);
+
+   const int min_arg_for_recursion = minimum_argument_for_bernoulli_recursion<T>();
+
+   T log_gamma_value;
+
+   if (zz < min_arg_for_recursion)
+   {
+      // Here we simply take the logarithm of tgamma(). This is somewhat
+      // inefficient, but simple. The rationale is that the argument here
+      // is relatively small and overflow is not expected to be likely.
+      if (sign)
+         * sign = 1;
+      if(fabs(z - 1) < 0.25)
+      {
+         log_gamma_value = log_gamma_near_1(T(zz - 1), pol);
+      }
+      else if(fabs(z - 2) < 0.25)
+      {
+         log_gamma_value = log_gamma_near_1(T(zz - 2), pol) + log(zz - 1);
+      }
+      else if (z > -tools::root_epsilon<T>())
+      {
+         // Reflection formula may fail if z is very close to zero, let the series
+         // expansion for tgamma close to zero do the work:
+         if (sign)
+            *sign = z < 0 ? -1 : 1;
+         return log(abs(gamma_imp(z, pol, lanczos::undefined_lanczos())));
+      }
+      else
+      {
+         // No issue with spurious overflow in reflection formula, 
+         // just fall through to regular code:
+         T g = gamma_imp(zz, pol, lanczos::undefined_lanczos());
+         if (sign)
+         {
+            *sign = g < 0 ? -1 : 1;
+         }
+         log_gamma_value = log(abs(g));
+      }
+   }
+   else
+   {
+      // Perform the Bernoulli series expansion of Stirling's approximation.
+      T sum = scaled_tgamma_no_lanczos(zz, pol, true);
+      log_gamma_value = zz * (log(zz) - 1) + sum;
+   }
+
+   int sign_of_result = 1;
+
+   if(b_neg)
+   {
+      // Provide special error analysis if the argument is exactly
+      // equal to a negative integer.
+
+      // Check if the argument of lgamma is exactly equal to a negative integer.
+      if(floor_of_z_is_equal_to_z)
+         return policies::raise_pole_error<T>(function, "Evaluation of lgamma at a negative integer %1%.", z, pol);
+
+      T t = sinpx(z);
+
+      if(t < 0)
+      {
+         t = -t;
+      }
+      else
+      {
+         sign_of_result = -sign_of_result;
+      }
+
+      log_gamma_value = - log_gamma_value
+                        + log(boost::math::constants::pi<T>())
+                        - log(t);
+   }
+
+   if(sign != static_cast<int*>(0U)) { *sign = sign_of_result; }
+
+   return log_gamma_value;
+}
+
+//
+// This helper calculates tgamma(dz+1)-1 without cancellation errors,
+// used by the upper incomplete gamma with z < 1:
+//
+template <class T, class Policy, class Lanczos>
+T tgammap1m1_imp(T dz, Policy const& pol, const Lanczos& l)
+{
+   BOOST_MATH_STD_USING
+
+   typedef typename policies::precision<T,Policy>::type precision_type;
+
+   typedef boost::integral_constant<int,
+      precision_type::value <= 0 ? 0 :
+      precision_type::value <= 64 ? 64 :
+      precision_type::value <= 113 ? 113 : 0
+   > tag_type;
+
+   T result;
+   if(dz < 0)
+   {
+      if(dz < -0.5)
+      {
+         // Best method is simply to subtract 1 from tgamma:
+         result = boost::math::tgamma(1+dz, pol) - 1;
+         BOOST_MATH_INSTRUMENT_CODE(result);
+      }
+      else
+      {
+         // Use expm1 on lgamma:
+         result = boost::math::expm1(-boost::math::log1p(dz, pol) 
+            + lgamma_small_imp<T>(dz+2, dz + 1, dz, tag_type(), pol, l));
+         BOOST_MATH_INSTRUMENT_CODE(result);
+      }
+   }
+   else
+   {
+      if(dz < 2)
+      {
+         // Use expm1 on lgamma:
+         result = boost::math::expm1(lgamma_small_imp<T>(dz+1, dz, dz-1, tag_type(), pol, l), pol);
+         BOOST_MATH_INSTRUMENT_CODE(result);
+      }
+      else
+      {
+         // Best method is simply to subtract 1 from tgamma:
+         result = boost::math::tgamma(1+dz, pol) - 1;
+         BOOST_MATH_INSTRUMENT_CODE(result);
+      }
+   }
+
+   return result;
+}
+
+template <class T, class Policy>
+inline T tgammap1m1_imp(T z, Policy const& pol,
+                 const ::boost::math::lanczos::undefined_lanczos&)
+{
+   BOOST_MATH_STD_USING // ADL of std names
+
+   if(fabs(z) < 0.55)
+   {
+      return boost::math::expm1(log_gamma_near_1(z, pol));
+   }
+   return boost::math::expm1(boost::math::lgamma(1 + z, pol));
+}
+
+//
+// Series representation for upper fraction when z is small:
+//
+template <class T>
+struct small_gamma2_series
+{
+   typedef T result_type;
+
+   small_gamma2_series(T a_, T x_) : result(-x_), x(-x_), apn(a_+1), n(1){}
+
+   T operator()()
+   {
+      T r = result / (apn);
+      result *= x;
+      result /= ++n;
+      apn += 1;
+      return r;
+   }
+
+private:
+   T result, x, apn;
+   int n;
+};
+//
+// calculate power term prefix (z^a)(e^-z) used in the non-normalised
+// incomplete gammas:
+//
+template <class T, class Policy>
+T full_igamma_prefix(T a, T z, const Policy& pol)
+{
+   BOOST_MATH_STD_USING
+
+   T prefix;
+   if (z > tools::max_value<T>())
+      return 0;
+   T alz = a * log(z);
+
+   if(z >= 1)
+   {
+      if((alz < tools::log_max_value<T>()) && (-z > tools::log_min_value<T>()))
+      {
+         prefix = pow(z, a) * exp(-z);
+      }
+      else if(a >= 1)
+      {
+         prefix = pow(z / exp(z/a), a);
+      }
+      else
+      {
+         prefix = exp(alz - z);
+      }
+   }
+   else
+   {
+      if(alz > tools::log_min_value<T>())
+      {
+         prefix = pow(z, a) * exp(-z);
+      }
+      else if(z/a < tools::log_max_value<T>())
+      {
+         prefix = pow(z / exp(z/a), a);
+      }
+      else
+      {
+         prefix = exp(alz - z);
+      }
+   }
+   //
+   // This error handling isn't very good: it happens after the fact
+   // rather than before it...
+   //
+   if((boost::math::fpclassify)(prefix) == (int)FP_INFINITE)
+      return policies::raise_overflow_error<T>("boost::math::detail::full_igamma_prefix<%1%>(%1%, %1%)", "Result of incomplete gamma function is too large to represent.", pol);
+
+   return prefix;
+}
+//
+// Compute (z^a)(e^-z)/tgamma(a)
+// most if the error occurs in this function:
+//
+template <class T, class Policy, class Lanczos>
+T regularised_gamma_prefix(T a, T z, const Policy& pol, const Lanczos& l)
+{
+   BOOST_MATH_STD_USING
+   if (z >= tools::max_value<T>())
+      return 0;
+   T agh = a + static_cast<T>(Lanczos::g()) - T(0.5);
+   T prefix;
+   T d = ((z - a) - static_cast<T>(Lanczos::g()) + T(0.5)) / agh;
+
+   if(a < 1)
+   {
+      //
+      // We have to treat a < 1 as a special case because our Lanczos
+      // approximations are optimised against the factorials with a > 1,
+      // and for high precision types especially (128-bit reals for example)
+      // very small values of a can give rather erroneous results for gamma
+      // unless we do this:
+      //
+      // TODO: is this still required?  Lanczos approx should be better now?
+      //
+      if(z <= tools::log_min_value<T>())
+      {
+         // Oh dear, have to use logs, should be free of cancellation errors though:
+         return exp(a * log(z) - z - lgamma_imp(a, pol, l));
+      }
+      else
+      {
+         // direct calculation, no danger of overflow as gamma(a) < 1/a
+         // for small a.
+         return pow(z, a) * exp(-z) / gamma_imp(a, pol, l);
+      }
+   }
+   else if((fabs(d*d*a) <= 100) && (a > 150))
+   {
+      // special case for large a and a ~ z.
+      prefix = a * boost::math::log1pmx(d, pol) + z * static_cast<T>(0.5 - Lanczos::g()) / agh;
+      prefix = exp(prefix);
+   }
+   else
+   {
+      //
+      // general case.
+      // direct computation is most accurate, but use various fallbacks
+      // for different parts of the problem domain:
+      //
+      T alz = a * log(z / agh);
+      T amz = a - z;
+      if(((std::min)(alz, amz) <= tools::log_min_value<T>()) || ((std::max)(alz, amz) >= tools::log_max_value<T>()))
+      {
+         T amza = amz / a;
+         if(((std::min)(alz, amz)/2 > tools::log_min_value<T>()) && ((std::max)(alz, amz)/2 < tools::log_max_value<T>()))
+         {
+            // compute square root of the result and then square it:
+            T sq = pow(z / agh, a / 2) * exp(amz / 2);
+            prefix = sq * sq;
+         }
+         else if(((std::min)(alz, amz)/4 > tools::log_min_value<T>()) && ((std::max)(alz, amz)/4 < tools::log_max_value<T>()) && (z > a))
+         {
+            // compute the 4th root of the result then square it twice:
+            T sq = pow(z / agh, a / 4) * exp(amz / 4);
+            prefix = sq * sq;
+            prefix *= prefix;
+         }
+         else if((amza > tools::log_min_value<T>()) && (amza < tools::log_max_value<T>()))
+         {
+            prefix = pow((z * exp(amza)) / agh, a);
+         }
+         else
+         {
+            prefix = exp(alz + amz);
+         }
+      }
+      else
+      {
+         prefix = pow(z / agh, a) * exp(amz);
+      }
+   }
+   prefix *= sqrt(agh / boost::math::constants::e<T>()) / Lanczos::lanczos_sum_expG_scaled(a);
+   return prefix;
+}
+//
+// And again, without Lanczos support:
+//
+template <class T, class Policy>
+T regularised_gamma_prefix(T a, T z, const Policy& pol, const lanczos::undefined_lanczos& l)
+{
+   BOOST_MATH_STD_USING
+
+   if((a < 1) && (z < 1))
+   {
+      // No overflow possible since the power terms tend to unity as a,z -> 0
+      return pow(z, a) * exp(-z) / boost::math::tgamma(a, pol);
+   }
+   else if(a > minimum_argument_for_bernoulli_recursion<T>())
+   {
+      T scaled_gamma = scaled_tgamma_no_lanczos(a, pol);
+      T power_term = pow(z / a, a / 2);
+      T a_minus_z = a - z;
+      if ((0 == power_term) || (fabs(a_minus_z) > tools::log_max_value<T>()))
+      {
+         // The result is probably zero, but we need to be sure:
+         return exp(a * log(z / a) + a_minus_z - log(scaled_gamma));
+      }
+      return (power_term * exp(a_minus_z)) * (power_term / scaled_gamma);
+   }
+   else
+   {
+      //
+      // Usual case is to calculate the prefix at a+shift and recurse down
+      // to the value we want:
+      //
+      const int min_z = minimum_argument_for_bernoulli_recursion<T>();
+      long shift = 1 + ltrunc(min_z - a);
+      T result = regularised_gamma_prefix(T(a + shift), z, pol, l);
+      if (result != 0)
+      {
+         for (long i = 0; i < shift; ++i)
+         {
+            result /= z;
+            result *= a + i;
+         }
+         return result;
+      }
+      else
+      {
+         // 
+         // We failed, most probably we have z << 1, try again, this time
+         // we calculate z^a e^-z / tgamma(a+shift), combining power terms
+         // as we go.  And again recurse down to the result.
+         //
+         T scaled_gamma = scaled_tgamma_no_lanczos(T(a + shift), pol);
+         T power_term_1 = pow(z / (a + shift), a);
+         T power_term_2 = pow(a + shift, -shift);
+         T power_term_3 = exp(a + shift - z);
+         if ((0 == power_term_1) || (0 == power_term_2) || (0 == power_term_3) || (fabs(a + shift - z) > tools::log_max_value<T>()))
+         {
+            // We have no test case that gets here, most likely the type T
+            // has a high precision but low exponent range:
+            return exp(a * log(z) - z - boost::math::lgamma(a, pol));
+         }
+         result = power_term_1 * power_term_2 * power_term_3 / scaled_gamma;
+         for (long i = 0; i < shift; ++i)
+         {
+            result *= a + i;
+         }
+         return result;
+      }
+   }
+}
+//
+// Upper gamma fraction for very small a:
+//
+template <class T, class Policy>
+inline T tgamma_small_upper_part(T a, T x, const Policy& pol, T* pgam = 0, bool invert = false, T* pderivative = 0)
+{
+   BOOST_MATH_STD_USING  // ADL of std functions.
+   //
+   // Compute the full upper fraction (Q) when a is very small:
+   //
+   T result;
+   result = boost::math::tgamma1pm1(a, pol);
+   if(pgam)
+      *pgam = (result + 1) / a;
+   T p = boost::math::powm1(x, a, pol);
+   result -= p;
+   result /= a;
+   detail::small_gamma2_series<T> s(a, x);
+   boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>() - 10;
+   p += 1;
+   if(pderivative)
+      *pderivative = p / (*pgam * exp(x));
+   T init_value = invert ? *pgam : 0;
+   result = -p * tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter, (init_value - result) / p);
+   policies::check_series_iterations<T>("boost::math::tgamma_small_upper_part<%1%>(%1%, %1%)", max_iter, pol);
+   if(invert)
+      result = -result;
+   return result;
+}
+//
+// Upper gamma fraction for integer a:
+//
+template <class T, class Policy>
+inline T finite_gamma_q(T a, T x, Policy const& pol, T* pderivative = 0)
+{
+   //
+   // Calculates normalised Q when a is an integer:
+   //
+   BOOST_MATH_STD_USING
+   T e = exp(-x);
+   T sum = e;
+   if(sum != 0)
+   {
+      T term = sum;
+      for(unsigned n = 1; n < a; ++n)
+      {
+         term /= n;
+         term *= x;
+         sum += term;
+      }
+   }
+   if(pderivative)
+   {
+      *pderivative = e * pow(x, a) / boost::math::unchecked_factorial<T>(itrunc(T(a - 1), pol));
+   }
+   return sum;
+}
+//
+// Upper gamma fraction for half integer a:
+//
+template <class T, class Policy>
+T finite_half_gamma_q(T a, T x, T* p_derivative, const Policy& pol)
+{
+   //
+   // Calculates normalised Q when a is a half-integer:
+   //
+   BOOST_MATH_STD_USING
+   T e = boost::math::erfc(sqrt(x), pol);
+   if((e != 0) && (a > 1))
+   {
+      T term = exp(-x) / sqrt(constants::pi<T>() * x);
+      term *= x;
+      static const T half = T(1) / 2;
+      term /= half;
+      T sum = term;
+      for(unsigned n = 2; n < a; ++n)
+      {
+         term /= n - half;
+         term *= x;
+         sum += term;
+      }
+      e += sum;
+      if(p_derivative)
+      {
+         *p_derivative = 0;
+      }
+   }
+   else if(p_derivative)
+   {
+      // We'll be dividing by x later, so calculate derivative * x:
+      *p_derivative = sqrt(x) * exp(-x) / constants::root_pi<T>();
+   }
+   return e;
+}
+//
+// Asymptotic approximation for large argument, see: https://dlmf.nist.gov/8.11#E2
+//
+template <class T>
+struct incomplete_tgamma_large_x_series
+{
+   typedef T result_type;
+   incomplete_tgamma_large_x_series(const T& a, const T& x)
+      : a_poch(a - 1), z(x), term(1) {}
+   T operator()()
+   {
+      T result = term;
+      term *= a_poch / z;
+      a_poch -= 1;
+      return result;
+   }
+   T a_poch, z, term;
+};
+
+template <class T, class Policy>
+T incomplete_tgamma_large_x(const T& a, const T& x, const Policy& pol)
+{
+   BOOST_MATH_STD_USING
+   incomplete_tgamma_large_x_series<T> s(a, x);
+   boost::uintmax_t max_iter = boost::math::policies::get_max_series_iterations<Policy>();
+   T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon<T, Policy>(), max_iter);
+   boost::math::policies::check_series_iterations<T>("boost::math::tgamma<%1%>(%1%,%1%)", max_iter, pol);
+   return result;
+}
+
+
+//
+// Main incomplete gamma entry point, handles all four incomplete gamma's:
+//
+template <class T, class Policy>
+T gamma_incomplete_imp(T a, T x, bool normalised, bool invert, 
+                       const Policy& pol, T* p_derivative)
+{
+   static const char* function = "boost::math::gamma_p<%1%>(%1%, %1%)";
+   if(a <= 0)
+      return policies::raise_domain_error<T>(function, "Argument a to the incomplete gamma function must be greater than zero (got a=%1%).", a, pol);
+   if(x < 0)
+      return policies::raise_domain_error<T>(function, "Argument x to the incomplete gamma function must be >= 0 (got x=%1%).", x, pol);
+
+   BOOST_MATH_STD_USING
+
+   typedef typename lanczos::lanczos<T, Policy>::type lanczos_type;
+
+   T result = 0; // Just to avoid warning C4701: potentially uninitialized local variable 'result' used
+
+   if(a >= max_factorial<T>::value && !normalised)
+   {
+      //
+      // When we're computing the non-normalized incomplete gamma
+      // and a is large the result is rather hard to compute unless
+      // we use logs.  There are really two options - if x is a long
+      // way from a in value then we can reliably use methods 2 and 4
+      // below in logarithmic form and go straight to the result.
+      // Otherwise we let the regularized gamma take the strain
+      // (the result is unlikely to underflow in the central region anyway)
+      // and combine with lgamma in the hopes that we get a finite result.
+      //
+      if(invert && (a * 4 < x))
+      {
+         // This is method 4 below, done in logs:
+         result = a * log(x) - x;
+         if(p_derivative)
+            *p_derivative = exp(result);
+         result += log(upper_gamma_fraction(a, x, policies::get_epsilon<T, Policy>()));
+      }
+      else if(!invert && (a > 4 * x))
+      {
+         // This is method 2 below, done in logs:
+         result = a * log(x) - x;
+         if(p_derivative)
+            *p_derivative = exp(result);
+         T init_value = 0;
+         result += log(detail::lower_gamma_series(a, x, pol, init_value) / a);
+      }
+      else
+      {
+         result = gamma_incomplete_imp(a, x, true, invert, pol, p_derivative);
+         if(result == 0)
+         {
+            if(invert)
+            {
+               // Try http://functions.wolfram.com/06.06.06.0039.01
+               result = 1 + 1 / (12 * a) + 1 / (288 * a * a);
+               result = log(result) - a + (a - 0.5f) * log(a) + log(boost::math::constants::root_two_pi<T>());
+               if(p_derivative)
+                  *p_derivative = exp(a * log(x) - x);
+            }
+            else
+            {
+               // This is method 2 below, done in logs, we're really outside the
+               // range of this method, but since the result is almost certainly
+               // infinite, we should probably be OK:
+               result = a * log(x) - x;
+               if(p_derivative)
+                  *p_derivative = exp(result);
+               T init_value = 0;
+               result += log(detail::lower_gamma_series(a, x, pol, init_value) / a);
+            }
+         }
+         else
+         {
+            result = log(result) + boost::math::lgamma(a, pol);
+         }
+      }
+      if(result > tools::log_max_value<T>())
+         return policies::raise_overflow_error<T>(function, 0, pol);
+      return exp(result);
+   }
+
+   BOOST_ASSERT((p_derivative == 0) || (normalised == true));
+
+   bool is_int, is_half_int;
+   bool is_small_a = (a < 30) && (a <= x + 1) && (x < tools::log_max_value<T>());
+   if(is_small_a)
+   {
+      T fa = floor(a);
+      is_int = (fa == a);
+      is_half_int = is_int ? false : (fabs(fa - a) == 0.5f);
+   }
+   else
+   {
+      is_int = is_half_int = false;
+   }
+
+   int eval_method;
+   
+   if(is_int && (x > 0.6))
+   {
+      // calculate Q via finite sum:
+      invert = !invert;
+      eval_method = 0;
+   }
+   else if(is_half_int && (x > 0.2))
+   {
+      // calculate Q via finite sum for half integer a:
+      invert = !invert;
+      eval_method = 1;
+   }
+   else if((x < tools::root_epsilon<T>()) && (a > 1))
+   {
+      eval_method = 6;
+   }
+   else if ((x > 1000) && ((a < x) || (fabs(a - 50) / x < 1)))
+   {
+      // calculate Q via asymptotic approximation:
+      invert = !invert;
+      eval_method = 7;
+   }
+   else if(x < 0.5)
+   {
+      //
+      // Changeover criterion chosen to give a changeover at Q ~ 0.33
+      //
+      if(-0.4 / log(x) < a)
+      {
+         eval_method = 2;
+      }
+      else
+      {
+         eval_method = 3;
+      }
+   }
+   else if(x < 1.1)
+   {
+      //
+      // Changover here occurs when P ~ 0.75 or Q ~ 0.25:
+      //
+      if(x * 0.75f < a)
+      {
+         eval_method = 2;
+      }
+      else
+      {
+         eval_method = 3;
+      }
+   }
+   else
+   {
+      //
+      // Begin by testing whether we're in the "bad" zone
+      // where the result will be near 0.5 and the usual
+      // series and continued fractions are slow to converge:
+      //
+      bool use_temme = false;
+      if(normalised && std::numeric_limits<T>::is_specialized && (a > 20))
+      {
+         T sigma = fabs((x-a)/a);
+         if((a > 200) && (policies::digits<T, Policy>() <= 113))
+         {
+            //
+            // This limit is chosen so that we use Temme's expansion
+            // only if the result would be larger than about 10^-6.
+            // Below that the regular series and continued fractions
+            // converge OK, and if we use Temme's method we get increasing
+            // errors from the dominant erfc term as it's (inexact) argument
+            // increases in magnitude.
+            //
+            if(20 / a > sigma * sigma)
+               use_temme = true;
+         }
+         else if(policies::digits<T, Policy>() <= 64)
+         {
+            // Note in this zone we can't use Temme's expansion for 
+            // types longer than an 80-bit real:
+            // it would require too many terms in the polynomials.
+            if(sigma < 0.4)
+               use_temme = true;
+         }
+      }
+      if(use_temme)
+      {
+         eval_method = 5;
+      }
+      else
+      {
+         //
+         // Regular case where the result will not be too close to 0.5.
+         //
+         // Changeover here occurs at P ~ Q ~ 0.5
+         // Note that series computation of P is about x2 faster than continued fraction
+         // calculation of Q, so try and use the CF only when really necessary, especially
+         // for small x.
+         //
+         if(x - (1 / (3 * x)) < a)
+         {
+            eval_method = 2;
+         }
+         else
+         {
+            eval_method = 4;
+            invert = !invert;
+         }
+      }
+   }
+
+   switch(eval_method)
+   {
+   case 0:
+      {
+         result = finite_gamma_q(a, x, pol, p_derivative);
+         if(normalised == false)
+            result *= boost::math::tgamma(a, pol);
+         break;
+      }
+   case 1:
+      {
+         result = finite_half_gamma_q(a, x, p_derivative, pol);
+         if(normalised == false)
+            result *= boost::math::tgamma(a, pol);
+         if(p_derivative && (*p_derivative == 0))
+            *p_derivative = regularised_gamma_prefix(a, x, pol, lanczos_type());
+         break;
+      }
+   case 2:
+      {
+         // Compute P:
+         result = normalised ? regularised_gamma_prefix(a, x, pol, lanczos_type()) : full_igamma_prefix(a, x, pol);
+         if(p_derivative)
+            *p_derivative = result;
+         if(result != 0)
+         {
+            //
+            // If we're going to be inverting the result then we can
+            // reduce the number of series evaluations by quite
+            // a few iterations if we set an initial value for the
+            // series sum based on what we'll end up subtracting it from
+            // at the end.
+            // Have to be careful though that this optimization doesn't 
+            // lead to spurious numeric overflow.  Note that the
+            // scary/expensive overflow checks below are more often
+            // than not bypassed in practice for "sensible" input
+            // values:
+            //
+            T init_value = 0;
+            bool optimised_invert = false;
+            if(invert)
+            {
+               init_value = (normalised ? 1 : boost::math::tgamma(a, pol));
+               if(normalised || (result >= 1) || (tools::max_value<T>() * result > init_value))
+               {
+                  init_value /= result;
+                  if(normalised || (a < 1) || (tools::max_value<T>() / a > init_value))
+                  {
+                     init_value *= -a;
+                     optimised_invert = true;
+                  }
+                  else
+                     init_value = 0;
+               }
+               else
+                  init_value = 0;
+            }
+            result *= detail::lower_gamma_series(a, x, pol, init_value) / a;
+            if(optimised_invert)
+            {
+               invert = false;
+               result = -result;
+            }
+         }
+         break;
+      }
+   case 3:
+      {
+         // Compute Q:
+         invert = !invert;
+         T g;
+         result = tgamma_small_upper_part(a, x, pol, &g, invert, p_derivative);
+         invert = false;
+         if(normalised)
+            result /= g;
+         break;
+      }
+   case 4:
+      {
+         // Compute Q:
+         result = normalised ? regularised_gamma_prefix(a, x, pol, lanczos_type()) : full_igamma_prefix(a, x, pol);
+         if(p_derivative)
+            *p_derivative = result;
+         if(result != 0)
+            result *= upper_gamma_fraction(a, x, policies::get_epsilon<T, Policy>());
+         break;
+      }
+   case 5:
+      {
+         //
+         // Use compile time dispatch to the appropriate
+         // Temme asymptotic expansion.  This may be dead code
+         // if T does not have numeric limits support, or has
+         // too many digits for the most precise version of
+         // these expansions, in that case we'll be calling
+         // an empty function.
+         //
+         typedef typename policies::precision<T, Policy>::type precision_type;
+
+         typedef boost::integral_constant<int,
+            precision_type::value <= 0 ? 0 :
+            precision_type::value <= 53 ? 53 :
+            precision_type::value <= 64 ? 64 :
+            precision_type::value <= 113 ? 113 : 0
+         > tag_type;
+
+         result = igamma_temme_large(a, x, pol, static_cast<tag_type const*>(0));
+         if(x >= a)
+            invert = !invert;
+         if(p_derivative)
+            *p_derivative = regularised_gamma_prefix(a, x, pol, lanczos_type());
+         break;
+      }
+   case 6:
+      {
+         // x is so small that P is necessarily very small too,
+         // use http://functions.wolfram.com/GammaBetaErf/GammaRegularized/06/01/05/01/01/
+         result = !normalised ? pow(x, a) / (a) : pow(x, a) / boost::math::tgamma(a + 1, pol);
+         result *= 1 - a * x / (a + 1);
+         if (p_derivative)
+            *p_derivative = regularised_gamma_prefix(a, x, pol, lanczos_type());
+         break;
+      }
+   case 7:
+   {
+      // x is large,
+      // Compute Q:
+      result = normalised ? regularised_gamma_prefix(a, x, pol, lanczos_type()) : full_igamma_prefix(a, x, pol);
+      if (p_derivative)
+         *p_derivative = result;
+      result /= x;
+      if (result != 0)
+         result *= incomplete_tgamma_large_x(a, x, pol);
+      break;
+   }
+   }
+
+   if(normalised && (result > 1))
+      result = 1;
+   if(invert)
+   {
+      T gam = normalised ? 1 : boost::math::tgamma(a, pol);
+      result = gam - result;
+   }
+   if(p_derivative)
+   {
+      //
+      // Need to convert prefix term to derivative:
+      //
+      if((x < 1) && (tools::max_value<T>() * x < *p_derivative))
+      {
+         // overflow, just return an arbitrarily large value:
+         *p_derivative = tools::max_value<T>() / 2;
+      }
+
+      *p_derivative /= x;
+   }
+
+   return result;
+}
+
+//
+// Ratios of two gamma functions:
+//
+template <class T, class Policy, class Lanczos>
+T tgamma_delta_ratio_imp_lanczos(T z, T delta, const Policy& pol, const Lanczos& l)
+{
+   BOOST_MATH_STD_USING
+   if(z < tools::epsilon<T>())
+   {
+      //
+      // We get spurious numeric overflow unless we're very careful, this
+      // can occur either inside Lanczos::lanczos_sum(z) or in the
+      // final combination of terms, to avoid this, split the product up
+      // into 2 (or 3) parts:
+      //
+      // G(z) / G(L) = 1 / (z * G(L)) ; z < eps, L = z + delta = delta
+      //    z * G(L) = z * G(lim) * (G(L)/G(lim)) ; lim = largest factorial
+      //
+      if(boost::math::max_factorial<T>::value < delta)
+      {
+         T ratio = tgamma_delta_ratio_imp_lanczos(delta, T(boost::math::max_factorial<T>::value - delta), pol, l);
+         ratio *= z;
+         ratio *= boost::math::unchecked_factorial<T>(boost::math::max_factorial<T>::value - 1);
+         return 1 / ratio;
+      }
+      else
+      {
+         return 1 / (z * boost::math::tgamma(z + delta, pol));
+      }
+   }
+   T zgh = static_cast<T>(z + Lanczos::g() - constants::half<T>());
+   T result;
+   if(z + delta == z)
+   {
+      if(fabs(delta) < 10)
+         result = exp((constants::half<T>() - z) * boost::math::log1p(delta / zgh, pol));
+      else
+         result = 1;
+   }
+   else
+   {
+      if(fabs(delta) < 10)
+      {
+         result = exp((constants::half<T>() - z) * boost::math::log1p(delta / zgh, pol));
+      }
+      else
+      {
+         result = pow(zgh / (zgh + delta), z - constants::half<T>());
+      }
+      // Split the calculation up to avoid spurious overflow:
+      result *= Lanczos::lanczos_sum(z) / Lanczos::lanczos_sum(T(z + delta));
+   }
+   result *= pow(constants::e<T>() / (zgh + delta), delta);
+   return result;
+}
+//
+// And again without Lanczos support this time:
+//
+template <class T, class Policy>
+T tgamma_delta_ratio_imp_lanczos(T z, T delta, const Policy& pol, const lanczos::undefined_lanczos& l)
+{
+   BOOST_MATH_STD_USING
+
+   //
+   // We adjust z and delta so that both z and z+delta are large enough for
+   // Sterling's approximation to hold.  We can then calculate the ratio
+   // for the adjusted values, and rescale back down to z and z+delta.
+   //
+   // Get the required shifts first:
+   //
+   long numerator_shift = 0;
+   long denominator_shift = 0;
+   const int min_z = minimum_argument_for_bernoulli_recursion<T>();
+   
+   if (min_z > z)
+      numerator_shift = 1 + ltrunc(min_z - z);
+   if (min_z > z + delta)
+      denominator_shift = 1 + ltrunc(min_z - z - delta);
+   //
+   // If the shifts are zero, then we can just combine scaled tgamma's
+   // and combine the remaining terms:
+   //
+   if (numerator_shift == 0 && denominator_shift == 0)
+   {
+      T scaled_tgamma_num = scaled_tgamma_no_lanczos(z, pol);
+      T scaled_tgamma_denom = scaled_tgamma_no_lanczos(T(z + delta), pol);
+      T result = scaled_tgamma_num / scaled_tgamma_denom;
+      result *= exp(z * boost::math::log1p(-delta / (z + delta), pol)) * pow((delta + z) / constants::e<T>(), -delta);
+      return result;
+   }
+   //
+   // We're going to have to rescale first, get the adjusted z and delta values,
+   // plus the ratio for the adjusted values:
+   //
+   T zz = z + numerator_shift;
+   T dd = delta - (numerator_shift - denominator_shift);
+   T ratio = tgamma_delta_ratio_imp_lanczos(zz, dd, pol, l);
+   //
+   // Use gamma recurrence relations to get back to the original
+   // z and z+delta:
+   //
+   for (long long i = 0; i < numerator_shift; ++i)
+   {
+      ratio /= (z + i);
+      if (i < denominator_shift)
+         ratio *= (z + delta + i);
+   }
+   for (long long i = numerator_shift; i < denominator_shift; ++i)
+   {
+      ratio *= (z + delta + i);
+   }
+   return ratio;
+}
+
+template <class T, class Policy>
+T tgamma_delta_ratio_imp(T z, T delta, const Policy& pol)
+{
+   BOOST_MATH_STD_USING
+
+   if((z <= 0) || (z + delta <= 0))
+   {
+      // This isn't very sophisticated, or accurate, but it does work:
+      return boost::math::tgamma(z, pol) / boost::math::tgamma(z + delta, pol);
+   }
+
+   if(floor(delta) == delta)
+   {
+      if(floor(z) == z)
+      {
+         //
+         // Both z and delta are integers, see if we can just use table lookup
+         // of the factorials to get the result:
+         //
+         if((z <= max_factorial<T>::value) && (z + delta <= max_factorial<T>::value))
+         {
+            return unchecked_factorial<T>((unsigned)itrunc(z, pol) - 1) / unchecked_factorial<T>((unsigned)itrunc(T(z + delta), pol) - 1);
+         }
+      }
+      if(fabs(delta) < 20)
+      {
+         //
+         // delta is a small integer, we can use a finite product:
+         //
+         if(delta == 0)
+            return 1;
+         if(delta < 0)
+         {
+            z -= 1;
+            T result = z;
+            while(0 != (delta += 1))
+            {
+               z -= 1;
+               result *= z;
+            }
+            return result;
+         }
+         else
+         {
+            T result = 1 / z;
+            while(0 != (delta -= 1))
+            {
+               z += 1;
+               result /= z;
+            }
+            return result;
+         }
+      }
+   }
+   typedef typename lanczos::lanczos<T, Policy>::type lanczos_type;
+   return tgamma_delta_ratio_imp_lanczos(z, delta, pol, lanczos_type());
+}
+
+template <class T, class Policy>
+T tgamma_ratio_imp(T x, T y, const Policy& pol)
+{
+   BOOST_MATH_STD_USING
+
+   if((x <= 0) || (boost::math::isinf)(x))
+      return policies::raise_domain_error<T>("boost::math::tgamma_ratio<%1%>(%1%, %1%)", "Gamma function ratios only implemented for positive arguments (got a=%1%).", x, pol);
+   if((y <= 0) || (boost::math::isinf)(y))
+      return policies::raise_domain_error<T>("boost::math::tgamma_ratio<%1%>(%1%, %1%)", "Gamma function ratios only implemented for positive arguments (got b=%1%).", y, pol);
+
+   if(x <= tools::min_value<T>())
+   {
+      // Special case for denorms...Ugh.
+      T shift = ldexp(T(1), tools::digits<T>());
+      return shift * tgamma_ratio_imp(T(x * shift), y, pol);
+   }
+
+   if((x < max_factorial<T>::value) && (y < max_factorial<T>::value))
+   {
+      // Rather than subtracting values, lets just call the gamma functions directly:
+      return boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol);
+   }
+   T prefix = 1;
+   if(x < 1)
+   {
+      if(y < 2 * max_factorial<T>::value)
+      {
+         // We need to sidestep on x as well, otherwise we'll underflow
+         // before we get to factor in the prefix term:
+         prefix /= x;
+         x += 1;
+         while(y >=  max_factorial<T>::value)
+         {
+            y -= 1;
+            prefix /= y;
+         }
+         return prefix * boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol);
+      }
+      //
+      // result is almost certainly going to underflow to zero, try logs just in case:
+      //
+      return exp(boost::math::lgamma(x, pol) - boost::math::lgamma(y, pol));
+   }
+   if(y < 1)
+   {
+      if(x < 2 * max_factorial<T>::value)
+      {
+         // We need to sidestep on y as well, otherwise we'll overflow
+         // before we get to factor in the prefix term:
+         prefix *= y;
+         y += 1;
+         while(x >= max_factorial<T>::value)
+         {
+            x -= 1;
+            prefix *= x;
+         }
+         return prefix * boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol);
+      }
+      //
+      // Result will almost certainly overflow, try logs just in case:
+      //
+      return exp(boost::math::lgamma(x, pol) - boost::math::lgamma(y, pol));
+   }
+   //
+   // Regular case, x and y both large and similar in magnitude:
+   //
+   return boost::math::tgamma_delta_ratio(x, y - x, pol);
+}
+
+template <class T, class Policy>
+T gamma_p_derivative_imp(T a, T x, const Policy& pol)
+{
+   BOOST_MATH_STD_USING
+   //
+   // Usual error checks first:
+   //
+   if(a <= 0)
+      return policies::raise_domain_error<T>("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", "Argument a to the incomplete gamma function must be greater than zero (got a=%1%).", a, pol);
+   if(x < 0)
+      return policies::raise_domain_error<T>("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", "Argument x to the incomplete gamma function must be >= 0 (got x=%1%).", x, pol);
+   //
+   // Now special cases:
+   //
+   if(x == 0)
+   {
+      return (a > 1) ? 0 :
+         (a == 1) ? 1 : policies::raise_overflow_error<T>("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", 0, pol);
+   }
+   //
+   // Normal case:
+   //
+   typedef typename lanczos::lanczos<T, Policy>::type lanczos_type;
+   T f1 = detail::regularised_gamma_prefix(a, x, pol, lanczos_type());
+   if((x < 1) && (tools::max_value<T>() * x < f1))
+   {
+      // overflow:
+      return policies::raise_overflow_error<T>("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", 0, pol);
+   }
+   if(f1 == 0)
+   {
+      // Underflow in calculation, use logs instead:
+      f1 = a * log(x) - x - lgamma(a, pol) - log(x);
+      f1 = exp(f1);
+   }
+   else
+      f1 /= x;
+
+   return f1;
+}
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type 
+   tgamma(T z, const Policy& /* pol */, const boost::true_type)
+{
+   BOOST_FPU_EXCEPTION_GUARD
+   typedef typename tools::promote_args<T>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::gamma_imp(static_cast<value_type>(z), forwarding_policy(), evaluation_type()), "boost::math::tgamma<%1%>(%1%)");
+}
+
+template <class T, class Policy>
+struct igamma_initializer
+{
+   struct init
+   {
+      init()
+      {
+         typedef typename policies::precision<T, Policy>::type precision_type;
+
+         typedef boost::integral_constant<int,
+            precision_type::value <= 0 ? 0 :
+            precision_type::value <= 53 ? 53 :
+            precision_type::value <= 64 ? 64 :
+            precision_type::value <= 113 ? 113 : 0
+         > tag_type;
+
+         do_init(tag_type());
+      }
+      template <int N>
+      static void do_init(const boost::integral_constant<int, N>&)
+      {
+         // If std::numeric_limits<T>::digits is zero, we must not call
+         // our initialization code here as the precision presumably
+         // varies at runtime, and will not have been set yet.  Plus the
+         // code requiring initialization isn't called when digits == 0.
+         if(std::numeric_limits<T>::digits)
+         {
+            boost::math::gamma_p(static_cast<T>(400), static_cast<T>(400), Policy());
+         }
+      }
+      static void do_init(const boost::integral_constant<int, 53>&){}
+      void force_instantiate()const{}
+   };
+   static const init initializer;
+   static void force_instantiate()
+   {
+      initializer.force_instantiate();
+   }
+};
+
+template <class T, class Policy>
+const typename igamma_initializer<T, Policy>::init igamma_initializer<T, Policy>::initializer;
+
+template <class T, class Policy>
+struct lgamma_initializer
+{
+   struct init
+   {
+      init()
+      {
+         typedef typename policies::precision<T, Policy>::type precision_type;
+         typedef boost::integral_constant<int,
+            precision_type::value <= 0 ? 0 :
+            precision_type::value <= 64 ? 64 :
+            precision_type::value <= 113 ? 113 : 0
+         > tag_type;
+
+         do_init(tag_type());
+      }
+      static void do_init(const boost::integral_constant<int, 64>&)
+      {
+         boost::math::lgamma(static_cast<T>(2.5), Policy());
+         boost::math::lgamma(static_cast<T>(1.25), Policy());
+         boost::math::lgamma(static_cast<T>(1.75), Policy());
+      }
+      static void do_init(const boost::integral_constant<int, 113>&)
+      {
+         boost::math::lgamma(static_cast<T>(2.5), Policy());
+         boost::math::lgamma(static_cast<T>(1.25), Policy());
+         boost::math::lgamma(static_cast<T>(1.5), Policy());
+         boost::math::lgamma(static_cast<T>(1.75), Policy());
+      }
+      static void do_init(const boost::integral_constant<int, 0>&)
+      {
+      }
+      void force_instantiate()const{}
+   };
+   static const init initializer;
+   static void force_instantiate()
+   {
+      initializer.force_instantiate();
+   }
+};
+
+template <class T, class Policy>
+const typename lgamma_initializer<T, Policy>::init lgamma_initializer<T, Policy>::initializer;
+
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+   tgamma(T1 a, T2 z, const Policy&, const boost::false_type)
+{
+   BOOST_FPU_EXCEPTION_GUARD
+   typedef typename tools::promote_args<T1, T2>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   // typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   igamma_initializer<value_type, forwarding_policy>::force_instantiate();
+
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+      detail::gamma_incomplete_imp(static_cast<value_type>(a),
+      static_cast<value_type>(z), false, true,
+      forwarding_policy(), static_cast<value_type*>(0)), "boost::math::tgamma<%1%>(%1%, %1%)");
+}
+
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+   tgamma(T1 a, T2 z, const boost::false_type& tag)
+{
+   return tgamma(a, z, policies::policy<>(), tag);
+}
+
+
+} // namespace detail
+
+template <class T>
+inline typename tools::promote_args<T>::type 
+   tgamma(T z)
+{
+   return tgamma(z, policies::policy<>());
+}
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type 
+   lgamma(T z, int* sign, const Policy&)
+{
+   BOOST_FPU_EXCEPTION_GUARD
+   typedef typename tools::promote_args<T>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   detail::lgamma_initializer<value_type, forwarding_policy>::force_instantiate();
+
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::lgamma_imp(static_cast<value_type>(z), forwarding_policy(), evaluation_type(), sign), "boost::math::lgamma<%1%>(%1%)");
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type 
+   lgamma(T z, int* sign)
+{
+   return lgamma(z, sign, policies::policy<>());
+}
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type 
+   lgamma(T x, const Policy& pol)
+{
+   return ::boost::math::lgamma(x, 0, pol);
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type 
+   lgamma(T x)
+{
+   return ::boost::math::lgamma(x, 0, policies::policy<>());
+}
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type 
+   tgamma1pm1(T z, const Policy& /* pol */)
+{
+   BOOST_FPU_EXCEPTION_GUARD
+   typedef typename tools::promote_args<T>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   return policies::checked_narrowing_cast<typename remove_cv<result_type>::type, forwarding_policy>(detail::tgammap1m1_imp(static_cast<value_type>(z), forwarding_policy(), evaluation_type()), "boost::math::tgamma1pm1<%!%>(%1%)");
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type 
+   tgamma1pm1(T z)
+{
+   return tgamma1pm1(z, policies::policy<>());
+}
+
+//
+// Full upper incomplete gamma:
+//
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+   tgamma(T1 a, T2 z)
+{
+   //
+   // Type T2 could be a policy object, or a value, select the 
+   // right overload based on T2:
+   //
+   typedef typename policies::is_policy<T2>::type maybe_policy;
+   return detail::tgamma(a, z, maybe_policy());
+}
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+   tgamma(T1 a, T2 z, const Policy& pol)
+{
+   return detail::tgamma(a, z, pol, boost::false_type());
+}
+//
+// Full lower incomplete gamma:
+//
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+   tgamma_lower(T1 a, T2 z, const Policy&)
+{
+   BOOST_FPU_EXCEPTION_GUARD
+   typedef typename tools::promote_args<T1, T2>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   // typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   detail::igamma_initializer<value_type, forwarding_policy>::force_instantiate();
+
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+      detail::gamma_incomplete_imp(static_cast<value_type>(a),
+      static_cast<value_type>(z), false, false,
+      forwarding_policy(), static_cast<value_type*>(0)), "tgamma_lower<%1%>(%1%, %1%)");
+}
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+   tgamma_lower(T1 a, T2 z)
+{
+   return tgamma_lower(a, z, policies::policy<>());
+}
+//
+// Regularised upper incomplete gamma:
+//
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+   gamma_q(T1 a, T2 z, const Policy& /* pol */)
+{
+   BOOST_FPU_EXCEPTION_GUARD
+   typedef typename tools::promote_args<T1, T2>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   // typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   detail::igamma_initializer<value_type, forwarding_policy>::force_instantiate();
+
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+      detail::gamma_incomplete_imp(static_cast<value_type>(a),
+      static_cast<value_type>(z), true, true,
+      forwarding_policy(), static_cast<value_type*>(0)), "gamma_q<%1%>(%1%, %1%)");
+}
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+   gamma_q(T1 a, T2 z)
+{
+   return gamma_q(a, z, policies::policy<>());
+}
+//
+// Regularised lower incomplete gamma:
+//
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type
+   gamma_p(T1 a, T2 z, const Policy&)
+{
+   BOOST_FPU_EXCEPTION_GUARD
+   typedef typename tools::promote_args<T1, T2>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   // typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   detail::igamma_initializer<value_type, forwarding_policy>::force_instantiate();
+
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+      detail::gamma_incomplete_imp(static_cast<value_type>(a),
+      static_cast<value_type>(z), true, false,
+      forwarding_policy(), static_cast<value_type*>(0)), "gamma_p<%1%>(%1%, %1%)");
+}
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type
+   gamma_p(T1 a, T2 z)
+{
+   return gamma_p(a, z, policies::policy<>());
+}
+
+// ratios of gamma functions:
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type 
+   tgamma_delta_ratio(T1 z, T2 delta, const Policy& /* pol */)
+{
+   BOOST_FPU_EXCEPTION_GUARD
+   typedef typename tools::promote_args<T1, T2>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::tgamma_delta_ratio_imp(static_cast<value_type>(z), static_cast<value_type>(delta), forwarding_policy()), "boost::math::tgamma_delta_ratio<%1%>(%1%, %1%)");
+}
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type 
+   tgamma_delta_ratio(T1 z, T2 delta)
+{
+   return tgamma_delta_ratio(z, delta, policies::policy<>());
+}
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type 
+   tgamma_ratio(T1 a, T2 b, const Policy&)
+{
+   typedef typename tools::promote_args<T1, T2>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::tgamma_ratio_imp(static_cast<value_type>(a), static_cast<value_type>(b), forwarding_policy()), "boost::math::tgamma_delta_ratio<%1%>(%1%, %1%)");
+}
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type 
+   tgamma_ratio(T1 a, T2 b)
+{
+   return tgamma_ratio(a, b, policies::policy<>());
+}
+
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type 
+   gamma_p_derivative(T1 a, T2 x, const Policy&)
+{
+   BOOST_FPU_EXCEPTION_GUARD
+   typedef typename tools::promote_args<T1, T2>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::gamma_p_derivative_imp(static_cast<value_type>(a), static_cast<value_type>(x), forwarding_policy()), "boost::math::gamma_p_derivative<%1%>(%1%, %1%)");
+}
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type 
+   gamma_p_derivative(T1 a, T2 x)
+{
+   return gamma_p_derivative(a, x, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#ifdef BOOST_MSVC
+# pragma warning(pop)
+#endif
+
+#include <boost/math/special_functions/detail/igamma_inverse.hpp>
+#include <boost/math/special_functions/detail/gamma_inva.hpp>
+#include <boost/math/special_functions/erf.hpp>
+
+#endif // BOOST_MATH_SF_GAMMA_HPP
+
+
+
+
diff --git a/ThirdParty/boost/math/special_functions/lanczos.hpp b/ThirdParty/boost/math/special_functions/lanczos.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5a68ad9539d3aa7b5683064c577915fbb3062c2c
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/lanczos.hpp
@@ -0,0 +1,3277 @@
+//  (C) Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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_SPECIAL_FUNCTIONS_LANCZOS
+#define BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/config.hpp>
+#include <boost/math/tools/big_constant.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/limits.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/math/tools/rational.hpp>
+#include <boost/math/policies/policy.hpp>
+#include <boost/mpl/less_equal.hpp>
+
+#include <limits.h>
+
+#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128)
+//
+// This is the only way we can avoid
+// warning: non-standard suffix on floating constant [-Wpedantic]
+// when building with -Wall -pedantic.  Neither __extension__
+// nor #pragma diagnostic ignored work :(
+//
+#pragma GCC system_header
+#endif
+
+namespace boost{ namespace math{ namespace lanczos{
+
+//
+// Individual lanczos approximations start here.
+//
+// Optimal values for G for each N are taken from
+// http://web.mala.bc.ca/pughg/phdThesis/phdThesis.pdf,
+// as are the theoretical error bounds.
+//
+// Constants calculated using the method described by Godfrey
+// http://my.fit.edu/~gabdo/gamma.txt and elaborated by Toth at
+// http://www.rskey.org/gamma.htm using NTL::RR at 1000 bit precision.
+//
+// Begin with a small helper to force initialization of constants prior
+// to main.  This makes the constant initialization thread safe, even
+// when called with a user-defined number type.
+//
+template <class Lanczos, class T>
+struct lanczos_initializer
+{
+   struct init
+   {
+      init()
+      {
+         T t(1);
+         Lanczos::lanczos_sum(t);
+         Lanczos::lanczos_sum_expG_scaled(t);
+         Lanczos::lanczos_sum_near_1(t);
+         Lanczos::lanczos_sum_near_2(t);
+         Lanczos::g();
+      }
+      void force_instantiate()const{}
+   };
+   static const init initializer;
+   static void force_instantiate()
+   {
+      initializer.force_instantiate();
+   }
+};
+template <class Lanczos, class T>
+typename lanczos_initializer<Lanczos, T>::init const lanczos_initializer<Lanczos, T>::initializer;
+//
+// Lanczos Coefficients for N=6 G=5.581
+// Max experimental error (with arbitrary precision arithmetic) 9.516e-12
+// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006
+//
+struct lanczos6 : public boost::integral_constant<int, 35>
+{
+   //
+   // Produces slightly better than float precision when evaluated at
+   // double precision:
+   //
+   template <class T>
+   static T lanczos_sum(const T& z)
+   {
+      lanczos_initializer<lanczos6, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T num[6] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 8706.349592549009182288174442774377925882)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 8523.650341121874633477483696775067709735)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 3338.029219476423550899999750161289306564)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 653.6424994294008795995653541449610986791)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 63.99951844938187085666201263218840287667)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 2.506628274631006311133031631822390264407))
+      };
+      static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint16_t) denom[6] = {
+         static_cast<boost::uint16_t>(0u),
+         static_cast<boost::uint16_t>(24u),
+         static_cast<boost::uint16_t>(50u),
+         static_cast<boost::uint16_t>(35u),
+         static_cast<boost::uint16_t>(10u),
+         static_cast<boost::uint16_t>(1u)
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+   template <class T>
+   static T lanczos_sum_expG_scaled(const T& z)
+   {
+      lanczos_initializer<lanczos6, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T num[6] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 32.81244541029783471623665933780748627823)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 32.12388941444332003446077108933558534361)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 12.58034729455216106950851080138931470954)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 2.463444478353241423633780693218408889251)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 0.2412010548258800231126240760264822486599)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 0.009446967704539249494420221613134244048319))
+      };
+      static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint16_t) denom[6] = {
+         static_cast<boost::uint16_t>(0u),
+         static_cast<boost::uint16_t>(24u),
+         static_cast<boost::uint16_t>(50u),
+         static_cast<boost::uint16_t>(35u),
+         static_cast<boost::uint16_t>(10u),
+         static_cast<boost::uint16_t>(1u)
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+
+   template<class T>
+   static T lanczos_sum_near_1(const T& dz)
+   {
+      lanczos_initializer<lanczos6, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T d[5] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 2.044879010930422922760429926121241330235)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, -2.751366405578505366591317846728753993668)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 1.02282965224225004296750609604264824677)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, -0.09786124911582813985028889636665335893627)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 0.0009829742267506615183144364420540766510112)),
+      };
+      T result = 0;
+      for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+      {
+         result += (-d[k-1]*dz)/(k*dz + k*k);
+      }
+      return result;
+   }
+
+   template<class T>
+   static T lanczos_sum_near_2(const T& dz)
+   {
+      lanczos_initializer<lanczos6, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T d[5] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 5.748142489536043490764289256167080091892)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, -7.734074268282457156081021756682138251825)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 2.875167944990511006997713242805893543947)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, -0.2750873773533504542306766137703788781776)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 35, 0.002763134585812698552178368447708846850353)),
+      };
+      T result = 0;
+      T z = dz + 2;
+      for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+      {
+         result += (-d[k-1]*dz)/(z + k*z + k*k - 1);
+      }
+      return result;
+   }
+
+   static double g(){ return 5.581000000000000405009359383257105946541; }
+};
+
+//
+// Lanczos Coefficients for N=11 G=10.900511
+// Max experimental error (with arbitrary precision arithmetic) 2.16676e-19
+// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006
+//
+struct lanczos11 : public boost::integral_constant<int, 60>
+{
+   //
+   // Produces slightly better than double precision when evaluated at
+   // extended-double precision:
+   //
+   template <class T>
+   static T lanczos_sum(const T& z)
+   {
+      lanczos_initializer<lanczos11, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T num[11] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 38474670393.31776828316099004518914832218)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 36857665043.51950660081971227404959150474)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 15889202453.72942008945006665994637853242)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 4059208354.298834770194507810788393801607)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 680547661.1834733286087695557084801366446)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 78239755.00312005289816041245285376206263)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 6246580.776401795264013335510453568106366)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 341986.3488721347032223777872763188768288)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 12287.19451182455120096222044424100527629)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 261.6140441641668190791708576058805625502)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 2.506628274631000502415573855452633787834))
+      };
+      static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint32_t) denom[11] = {
+         static_cast<boost::uint32_t>(0u),
+         static_cast<boost::uint32_t>(362880u),
+         static_cast<boost::uint32_t>(1026576u),
+         static_cast<boost::uint32_t>(1172700u),
+         static_cast<boost::uint32_t>(723680u),
+         static_cast<boost::uint32_t>(269325u),
+         static_cast<boost::uint32_t>(63273u),
+         static_cast<boost::uint32_t>(9450u),
+         static_cast<boost::uint32_t>(870u),
+         static_cast<boost::uint32_t>(45u),
+         static_cast<boost::uint32_t>(1u)
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+   template <class T>
+   static T lanczos_sum_expG_scaled(const T& z)
+   {
+      lanczos_initializer<lanczos11, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T num[11] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 709811.662581657956893540610814842699825)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 679979.847415722640161734319823103390728)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 293136.785721159725251629480984140341656)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 74887.5403291467179935942448101441897121)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 12555.29058241386295096255111537516768137)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 1443.42992444170669746078056942194198252)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 115.2419459613734722083208906727972935065)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 6.30923920573262762719523981992008976989)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 0.2266840463022436475495508977579735223818)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 0.004826466289237661857584712046231435101741)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 0.4624429436045378766270459638520555557321e-4))
+      };
+      static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint32_t) denom[11] = {
+         static_cast<boost::uint32_t>(0u),
+         static_cast<boost::uint32_t>(362880u),
+         static_cast<boost::uint32_t>(1026576u),
+         static_cast<boost::uint32_t>(1172700u),
+         static_cast<boost::uint32_t>(723680u),
+         static_cast<boost::uint32_t>(269325u),
+         static_cast<boost::uint32_t>(63273u),
+         static_cast<boost::uint32_t>(9450u),
+         static_cast<boost::uint32_t>(870u),
+         static_cast<boost::uint32_t>(45u),
+         static_cast<boost::uint32_t>(1u)
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+
+   template<class T>
+   static T lanczos_sum_near_1(const T& dz)
+   {
+      lanczos_initializer<lanczos11, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T d[10] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 4.005853070677940377969080796551266387954)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -13.17044315127646469834125159673527183164)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 17.19146865350790353683895137079288129318)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -11.36446409067666626185701599196274701126)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 4.024801119349323770107694133829772634737)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -0.7445703262078094128346501724255463005006)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 0.06513861351917497265045550019547857713172)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -0.00217899958561830354633560009312512312758)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 0.17655204574495137651670832229571934738e-4)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -0.1036282091079938047775645941885460820853e-7)),
+      };
+      T result = 0;
+      for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+      {
+         result += (-d[k-1]*dz)/(k*dz + k*k);
+      }
+      return result;
+   }
+
+   template<class T>
+   static T lanczos_sum_near_2(const T& dz)
+   {
+      lanczos_initializer<lanczos11, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T d[10] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 19.05889633808148715159575716844556056056)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -62.66183664701721716960978577959655644762)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 81.7929198065004751699057192860287512027)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -54.06941772964234828416072865069196553015)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 19.14904664790693019642068229478769661515)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -3.542488556926667589704590409095331790317)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 0.3099140334815639910894627700232804503017)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -0.01036716187296241640634252431913030440825)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, 0.8399926504443119927673843789048514017761e-4)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 60, -0.493038376656195010308610694048822561263e-7)),
+      };
+      T result = 0;
+      T z = dz + 2;
+      for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+      {
+         result += (-d[k-1]*dz)/(z + k*z + k*k - 1);
+      }
+      return result;
+   }
+
+   static double g(){ return 10.90051099999999983936049829935654997826; }
+};
+
+//
+// Lanczos Coefficients for N=13 G=13.144565
+// Max experimental error (with arbitrary precision arithmetic) 9.2213e-23
+// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006
+//
+struct lanczos13 : public boost::integral_constant<int, 72>
+{
+   //
+   // Produces slightly better than extended-double precision when evaluated at
+   // higher precision:
+   //
+   template <class T>
+   static T lanczos_sum(const T& z)
+   {
+      lanczos_initializer<lanczos13, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T num[13] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 44012138428004.60895436261759919070125699)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 41590453358593.20051581730723108131357995)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 18013842787117.99677796276038389462742949)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 4728736263475.388896889723995205703970787)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 837910083628.4046470415724300225777912264)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 105583707273.4299344907359855510105321192)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 9701363618.494999493386608345339104922694)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 654914397.5482052641016767125048538245644)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 32238322.94213356530668889463945849409184)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 1128514.219497091438040721811544858643121)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 26665.79378459858944762533958798805525125)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 381.8801248632926870394389468349331394196)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 2.506628274631000502415763426076722427007))
+      };
+      static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint32_t) denom[13] = {
+         static_cast<boost::uint32_t>(0u),
+         static_cast<boost::uint32_t>(39916800u),
+         static_cast<boost::uint32_t>(120543840u),
+         static_cast<boost::uint32_t>(150917976u),
+         static_cast<boost::uint32_t>(105258076u),
+         static_cast<boost::uint32_t>(45995730u),
+         static_cast<boost::uint32_t>(13339535u),
+         static_cast<boost::uint32_t>(2637558u),
+         static_cast<boost::uint32_t>(357423u),
+         static_cast<boost::uint32_t>(32670u),
+         static_cast<boost::uint32_t>(1925u),
+         static_cast<boost::uint32_t>(66u),
+         static_cast<boost::uint32_t>(1u)
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+   template <class T>
+   static T lanczos_sum_expG_scaled(const T& z)
+   {
+      lanczos_initializer<lanczos13, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T num[13] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 86091529.53418537217994842267760536134841)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 81354505.17858011242874285785316135398567)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 35236626.38815461910817650960734605416521)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 9249814.988024471294683815872977672237195)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 1639024.216687146960253839656643518985826)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 206530.8157641225032631778026076868855623)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 18976.70193530288915698282139308582105936)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 1281.068909912559479885759622791374106059)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 63.06093343420234536146194868906771599354)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 2.207470909792527638222674678171050209691)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 0.05216058694613505427476207805814960742102)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 0.0007469903808915448316510079585999893674101)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 0.4903180573459871862552197089738373164184e-5))
+      };
+      static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint32_t) denom[13] = {
+         static_cast<boost::uint32_t>(0u),
+         static_cast<boost::uint32_t>(39916800u),
+         static_cast<boost::uint32_t>(120543840u),
+         static_cast<boost::uint32_t>(150917976u),
+         static_cast<boost::uint32_t>(105258076u),
+         static_cast<boost::uint32_t>(45995730u),
+         static_cast<boost::uint32_t>(13339535u),
+         static_cast<boost::uint32_t>(2637558u),
+         static_cast<boost::uint32_t>(357423u),
+         static_cast<boost::uint32_t>(32670u),
+         static_cast<boost::uint32_t>(1925u),
+         static_cast<boost::uint32_t>(66u),
+         static_cast<boost::uint32_t>(1u)
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+
+   template<class T>
+   static T lanczos_sum_near_1(const T& dz)
+   {
+      lanczos_initializer<lanczos13, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T d[12] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 4.832115561461656947793029596285626840312)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -19.86441536140337740383120735104359034688)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 33.9927422807443239927197864963170585331)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -31.41520692249765980987427413991250886138)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 17.0270866009599345679868972409543597821)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -5.5077216950865501362506920516723682167)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 1.037811741948214855286817963800439373362)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -0.106640468537356182313660880481398642811)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 0.005276450526660653288757565778182586742831)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -0.0001000935625597121545867453746252064770029)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 0.462590910138598083940803704521211569234e-6)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -0.1735307814426389420248044907765671743012e-9)),
+      };
+      T result = 0;
+      for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+      {
+         result += (-d[k-1]*dz)/(k*dz + k*k);
+      }
+      return result;
+   }
+
+   template<class T>
+   static T lanczos_sum_near_2(const T& dz)
+   {
+      lanczos_initializer<lanczos13, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T d[12] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 26.96979819614830698367887026728396466395)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -110.8705424709385114023884328797900204863)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 189.7258846119231466417015694690434770085)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -175.3397202971107486383321670769397356553)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 95.03437648691551457087250340903980824948)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -30.7406022781665264273675797983497141978)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 5.792405601630517993355102578874590410552)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -0.5951993240669148697377539518639997795831)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 0.02944979359164017509944724739946255067671)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -0.0005586586555377030921194246330399163602684)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, 0.2581888478270733025288922038673392636029e-5)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 72, -0.9685385411006641478305219367315965391289e-9)),
+      };
+      T result = 0;
+      T z = dz + 2;
+      for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+      {
+         result += (-d[k-1]*dz)/(z + k*z + k*k - 1);
+      }
+      return result;
+   }
+
+   static double g(){ return 13.1445650000000000545696821063756942749; }
+};
+
+//
+// Lanczos Coefficients for N=22 G=22.61891
+// Max experimental error (with arbitrary precision arithmetic) 2.9524e-38
+// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006
+//
+struct lanczos22 : public boost::integral_constant<int, 120>
+{
+   //
+   // Produces slightly better than 128-bit long-double precision when 
+   // evaluated at higher precision:
+   //
+   template <class T>
+   static T lanczos_sum(const T& z)
+   {
+      lanczos_initializer<lanczos22, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T num[22] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 46198410803245094237463011094.12173081986)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 43735859291852324413622037436.321513777)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 19716607234435171720534556386.97481377748)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 5629401471315018442177955161.245623932129)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1142024910634417138386281569.245580222392)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 175048529315951173131586747.695329230778)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 21044290245653709191654675.41581372963167)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 2033001410561031998451380.335553678782601)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 160394318862140953773928.8736211601848891)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 10444944438396359705707.48957290388740896)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 565075825801617290121.1466393747967538948)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 25475874292116227538.99448534450411942597)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 957135055846602154.6720835535232270205725)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 29874506304047462.23662392445173880821515)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 769651310384737.2749087590725764959689181)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 16193289100889.15989633624378404096011797)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 273781151680.6807433264462376754578933261)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 3630485900.32917021712188739762161583295)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 36374352.05577334277856865691538582936484)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 258945.7742115532455441786924971194951043)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1167.501919472435718934219997431551246996)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 2.50662827463100050241576528481104525333))
+      };
+      static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint64_t) denom[22] = {
+         BOOST_MATH_INT_VALUE_SUFFIX(0, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(2432902008176640000, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(8752948036761600000, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(13803759753640704000, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(12870931245150988800, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(8037811822645051776, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(3599979517947607200, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(1206647803780373360, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(311333643161390640, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(63030812099294896, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(10142299865511450, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(1307535010540395, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(135585182899530, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(11310276995381, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(756111184500, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(40171771630, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(1672280820, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(53327946, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(1256850, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(20615, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(210, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(1, uLL)
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+   template <class T>
+   static T lanczos_sum_expG_scaled(const T& z)
+   {
+      lanczos_initializer<lanczos22, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T num[22] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 6939996264376682180.277485395074954356211)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 6570067992110214451.87201438870245659384)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 2961859037444440551.986724631496417064121)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 845657339772791245.3541226499766163431651)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 171556737035449095.2475716923888737881837)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 26296059072490867.7822441885603400926007)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 3161305619652108.433798300149816829198706)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 305400596026022.4774396904484542582526472)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 24094681058862.55120507202622377623528108)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1569055604375.919477574824168939428328839)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 84886558909.02047889339710230696942513159)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 3827024985.166751989686050643579753162298)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 143782298.9273215199098728674282885500522)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 4487794.24541641841336786238909171265944)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 115618.2025760830513505888216285273541959)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 2432.580773108508276957461757328744780439)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 41.12782532742893597168530008461874360191)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.5453771709477689805460179187388702295792)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.005464211062612080347167337964166505282809)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.388992321263586767037090706042788910953e-4)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.1753839324538447655939518484052327068859e-6)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.3765495513732730583386223384116545391759e-9))
+      };
+      static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint64_t) denom[22] = {
+         BOOST_MATH_INT_VALUE_SUFFIX(0, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(2432902008176640000, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(8752948036761600000, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(13803759753640704000, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(12870931245150988800, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(8037811822645051776, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(3599979517947607200, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(1206647803780373360, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(311333643161390640, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(63030812099294896, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(10142299865511450, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(1307535010540395, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(135585182899530, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(11310276995381, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(756111184500, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(40171771630, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(1672280820, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(53327946, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(1256850, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(20615, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(210, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(1, uLL)
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+
+   template<class T>
+   static T lanczos_sum_near_1(const T& dz)
+   {
+      lanczos_initializer<lanczos22, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T d[21] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 8.318998691953337183034781139546384476554)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -63.15415991415959158214140353299240638675)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 217.3108224383632868591462242669081540163)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -448.5134281386108366899784093610397354889)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 619.2903759363285456927248474593012711346)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -604.1630177420625418522025080080444177046)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 428.8166750424646119935047118287362193314)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -224.6988753721310913866347429589434550302)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 87.32181627555510833499451817622786940961)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -25.07866854821128965662498003029199058098)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 5.264398125689025351448861011657789005392)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.792518936256495243383586076579921559914)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.08317448364744713773350272460937904691566)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.005845345166274053157781068150827567998882)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.0002599412126352082483326238522490030412391)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.6748102079670763884917431338234783496303e-5)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.908824383434109002762325095643458603605e-7)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.5299325929309389890892469299969669579725e-9)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.994306085859549890267983602248532869362e-12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.3499893692975262747371544905820891835298e-15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.7260746353663365145454867069182884694961e-20)),
+      };
+      T result = 0;
+      for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+      {
+         result += (-d[k-1]*dz)/(k*dz + k*k);
+      }
+      return result;
+   }
+
+   template<class T>
+   static T lanczos_sum_near_2(const T& dz)
+   {
+      lanczos_initializer<lanczos22, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T d[21] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 75.39272007105208086018421070699575462226)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -572.3481967049935412452681346759966390319)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1969.426202741555335078065370698955484358)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -4064.74968778032030891520063865996757519)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 5612.452614138013929794736248384309574814)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -5475.357667500026172903620177988213902339)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 3886.243614216111328329547926490398103492)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -2036.382026072125407192448069428134470564)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 791.3727954936062108045551843636692287652)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -227.2808432388436552794021219198885223122)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 47.70974355562144229897637024320739257284)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -7.182373807798293545187073539819697141572)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.7537866989631514559601547530490976100468)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.05297470142240154822658739758236594717787)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.00235577330936380542539812701472320434133)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.6115613067659273118098229498679502138802e-4)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.8236417010170941915758315020695551724181e-6)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.4802628430993048190311242611330072198089e-8)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.9011113376981524418952720279739624707342e-11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.3171854152689711198382455703658589996796e-14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.6580207998808093935798753964580596673177e-19)),
+      };
+      T result = 0;
+      T z = dz + 2;
+      for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+      {
+         result += (-d[k-1]*dz)/(z + k*z + k*k - 1);
+      }
+      return result;
+   }
+
+   static double g(){ return 22.61890999999999962710717227309942245483; }
+};
+
+//
+// Lanczos Coefficients for N=6 G=1.428456135094165802001953125
+// Max experimental error (with arbitrary precision arithmetic) 8.111667e-8
+// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006
+//
+struct lanczos6m24 : public boost::integral_constant<int, 24>
+{
+   //
+   // Use for float precision, when evaluated as a float:
+   //
+   template <class T>
+   static T lanczos_sum(const T& z)
+   {
+      static const T num[6] = {
+         static_cast<T>(58.52061591769095910314047740215847630266L),
+         static_cast<T>(182.5248962595894264831189414768236280862L),
+         static_cast<T>(211.0971093028510041839168287718170827259L),
+         static_cast<T>(112.2526547883668146736465390902227161763L),
+         static_cast<T>(27.5192015197455403062503721613097825345L),
+         static_cast<T>(2.50662858515256974113978724717473206342L)
+      };
+      static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint16_t) denom[6] = {
+         static_cast<boost::uint16_t>(0u),
+         static_cast<boost::uint16_t>(24u),
+         static_cast<boost::uint16_t>(50u),
+         static_cast<boost::uint16_t>(35u),
+         static_cast<boost::uint16_t>(10u),
+         static_cast<boost::uint16_t>(1u)
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+   template <class T>
+   static T lanczos_sum_expG_scaled(const T& z)
+   {
+      static const T num[6] = {
+         static_cast<T>(14.0261432874996476619570577285003839357L),
+         static_cast<T>(43.74732405540314316089531289293124360129L),
+         static_cast<T>(50.59547402616588964511581430025589038612L),
+         static_cast<T>(26.90456680562548195593733429204228910299L),
+         static_cast<T>(6.595765571169314946316366571954421695196L),
+         static_cast<T>(0.6007854010515290065101128585795542383721L)
+      };
+      static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint16_t) denom[6] = {
+         static_cast<boost::uint16_t>(0u),
+         static_cast<boost::uint16_t>(24u),
+         static_cast<boost::uint16_t>(50u),
+         static_cast<boost::uint16_t>(35u),
+         static_cast<boost::uint16_t>(10u),
+         static_cast<boost::uint16_t>(1u)
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+
+   template<class T>
+   static T lanczos_sum_near_1(const T& dz)
+   {
+      static const T d[5] = {
+         static_cast<T>(0.4922488055204602807654354732674868442106L),
+         static_cast<T>(0.004954497451132152436631238060933905650346L),
+         static_cast<T>(-0.003374784572167105840686977985330859371848L),
+         static_cast<T>(0.001924276018962061937026396537786414831385L),
+         static_cast<T>(-0.00056533046336427583708166383712907694434L),
+      };
+      T result = 0;
+      for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+      {
+         result += (-d[k-1]*dz)/(k*dz + k*k);
+      }
+      return result;
+   }
+
+   template<class T>
+   static T lanczos_sum_near_2(const T& dz)
+   {
+      static const T d[5] = {
+         static_cast<T>(0.6534966888520080645505805298901130485464L),
+         static_cast<T>(0.006577461728560758362509168026049182707101L),
+         static_cast<T>(-0.004480276069269967207178373559014835978161L),
+         static_cast<T>(0.00255461870648818292376982818026706528842L),
+         static_cast<T>(-0.000750517993690428370380996157470900204524L),
+      };
+      T result = 0;
+      T z = dz + 2;
+      for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+      {
+         result += (-d[k-1]*dz)/(z + k*z + k*k - 1);
+      }
+      return result;
+   }
+
+   static double g(){ return 1.428456135094165802001953125; }
+};
+
+//
+// Lanczos Coefficients for N=13 G=6.024680040776729583740234375
+// Max experimental error (with arbitrary precision arithmetic) 1.196214e-17
+// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006
+//
+struct lanczos13m53 : public boost::integral_constant<int, 53>
+{
+   //
+   // Use for double precision, when evaluated as a double:
+   //
+   template <class T>
+   static T lanczos_sum(const T& z)
+   {
+      static const T num[13] = {
+         static_cast<T>(23531376880.41075968857200767445163675473L),
+         static_cast<T>(42919803642.64909876895789904700198885093L),
+         static_cast<T>(35711959237.35566804944018545154716670596L),
+         static_cast<T>(17921034426.03720969991975575445893111267L),
+         static_cast<T>(6039542586.35202800506429164430729792107L),
+         static_cast<T>(1439720407.311721673663223072794912393972L),
+         static_cast<T>(248874557.8620541565114603864132294232163L),
+         static_cast<T>(31426415.58540019438061423162831820536287L),
+         static_cast<T>(2876370.628935372441225409051620849613599L),
+         static_cast<T>(186056.2653952234950402949897160456992822L),
+         static_cast<T>(8071.672002365816210638002902272250613822L),
+         static_cast<T>(210.8242777515793458725097339207133627117L),
+         static_cast<T>(2.506628274631000270164908177133837338626L)
+      };
+      static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint32_t) denom[13] = {
+         static_cast<boost::uint32_t>(0u),
+         static_cast<boost::uint32_t>(39916800u),
+         static_cast<boost::uint32_t>(120543840u),
+         static_cast<boost::uint32_t>(150917976u),
+         static_cast<boost::uint32_t>(105258076u),
+         static_cast<boost::uint32_t>(45995730u),
+         static_cast<boost::uint32_t>(13339535u),
+         static_cast<boost::uint32_t>(2637558u),
+         static_cast<boost::uint32_t>(357423u),
+         static_cast<boost::uint32_t>(32670u),
+         static_cast<boost::uint32_t>(1925u),
+         static_cast<boost::uint32_t>(66u),
+         static_cast<boost::uint32_t>(1u)
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+   template <class T>
+   static T lanczos_sum_expG_scaled(const T& z)
+   {
+      static const T num[13] = {
+         static_cast<T>(56906521.91347156388090791033559122686859L),
+         static_cast<T>(103794043.1163445451906271053616070238554L),
+         static_cast<T>(86363131.28813859145546927288977868422342L),
+         static_cast<T>(43338889.32467613834773723740590533316085L),
+         static_cast<T>(14605578.08768506808414169982791359218571L),
+         static_cast<T>(3481712.15498064590882071018964774556468L),
+         static_cast<T>(601859.6171681098786670226533699352302507L),
+         static_cast<T>(75999.29304014542649875303443598909137092L),
+         static_cast<T>(6955.999602515376140356310115515198987526L),
+         static_cast<T>(449.9445569063168119446858607650988409623L),
+         static_cast<T>(19.51992788247617482847860966235652136208L),
+         static_cast<T>(0.5098416655656676188125178644804694509993L),
+         static_cast<T>(0.006061842346248906525783753964555936883222L)
+      };
+      static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint32_t) denom[13] = {
+         static_cast<boost::uint32_t>(0u),
+         static_cast<boost::uint32_t>(39916800u),
+         static_cast<boost::uint32_t>(120543840u),
+         static_cast<boost::uint32_t>(150917976u),
+         static_cast<boost::uint32_t>(105258076u),
+         static_cast<boost::uint32_t>(45995730u),
+         static_cast<boost::uint32_t>(13339535u),
+         static_cast<boost::uint32_t>(2637558u),
+         static_cast<boost::uint32_t>(357423u),
+         static_cast<boost::uint32_t>(32670u),
+         static_cast<boost::uint32_t>(1925u),
+         static_cast<boost::uint32_t>(66u),
+         static_cast<boost::uint32_t>(1u)
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+
+   template<class T>
+   static T lanczos_sum_near_1(const T& dz)
+   {
+      static const T d[12] = {
+         static_cast<T>(2.208709979316623790862569924861841433016L),
+         static_cast<T>(-3.327150580651624233553677113928873034916L),
+         static_cast<T>(1.483082862367253753040442933770164111678L),
+         static_cast<T>(-0.1993758927614728757314233026257810172008L),
+         static_cast<T>(0.004785200610085071473880915854204301886437L),
+         static_cast<T>(-0.1515973019871092388943437623825208095123e-5L),
+         static_cast<T>(-0.2752907702903126466004207345038327818713e-7L),
+         static_cast<T>(0.3075580174791348492737947340039992829546e-7L),
+         static_cast<T>(-0.1933117898880828348692541394841204288047e-7L),
+         static_cast<T>(0.8690926181038057039526127422002498960172e-8L),
+         static_cast<T>(-0.2499505151487868335680273909354071938387e-8L),
+         static_cast<T>(0.3394643171893132535170101292240837927725e-9L),
+      };
+      T result = 0;
+      for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+      {
+         result += (-d[k-1]*dz)/(k*dz + k*k);
+      }
+      return result;
+   }
+
+   template<class T>
+   static T lanczos_sum_near_2(const T& dz)
+   {
+      static const T d[12] = {
+         static_cast<T>(6.565936202082889535528455955485877361223L),
+         static_cast<T>(-9.8907772644920670589288081640128194231L),
+         static_cast<T>(4.408830289125943377923077727900630927902L),
+         static_cast<T>(-0.5926941084905061794445733628891024027949L),
+         static_cast<T>(0.01422519127192419234315002746252160965831L),
+         static_cast<T>(-0.4506604409707170077136555010018549819192e-5L),
+         static_cast<T>(-0.8183698410724358930823737982119474130069e-7L),
+         static_cast<T>(0.9142922068165324132060550591210267992072e-7L),
+         static_cast<T>(-0.5746670642147041587497159649318454348117e-7L),
+         static_cast<T>(0.2583592566524439230844378948704262291927e-7L),
+         static_cast<T>(-0.7430396708998719707642735577238449585822e-8L),
+         static_cast<T>(0.1009141566987569892221439918230042368112e-8L),
+      };
+      T result = 0;
+      T z = dz + 2;
+      for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+      {
+         result += (-d[k-1]*dz)/(z + k*z + k*k - 1);
+      }
+      return result;
+   }
+
+   static double g(){ return 6.024680040776729583740234375; }
+};
+
+//
+// Lanczos Coefficients for N=17 G=12.2252227365970611572265625
+// Max experimental error (with arbitrary precision arithmetic) 2.7699e-26
+// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006
+//
+struct lanczos17m64 : public boost::integral_constant<int, 64>
+{
+   //
+   // Use for extended-double precision, when evaluated as an extended-double:
+   //
+   template <class T>
+   static T lanczos_sum(const T& z)
+   {
+      lanczos_initializer<lanczos17m64, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T num[17] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 553681095419291969.2230556393350368550504)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 731918863887667017.2511276782146694632234)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 453393234285807339.4627124634539085143364)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 174701893724452790.3546219631779712198035)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 46866125995234723.82897281620357050883077)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 9281280675933215.169109622777099699054272)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1403600894156674.551057997617468721789536)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 165345984157572.7305349809894046783973837)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 15333629842677.31531822808737907246817024)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1123152927963.956626161137169462874517318)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 64763127437.92329018717775593533620578237)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 2908830362.657527782848828237106640944457)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 99764700.56999856729959383751710026787811)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 2525791.604886139959837791244686290089331)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 44516.94034970167828580039370201346554872)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 488.0063567520005730476791712814838113252)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 2.50662827463100050241576877135758834683))
+      };
+      static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint64_t) denom[17] = {
+         BOOST_MATH_INT_VALUE_SUFFIX(0, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(1307674368000, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(4339163001600, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(6165817614720, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(5056995703824, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(2706813345600, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(1009672107080, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(272803210680, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(54631129553, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(8207628000, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(928095740, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(78558480, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(4899622, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(218400, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(6580, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(120, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(1, uLL)
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+   template <class T>
+   static T lanczos_sum_expG_scaled(const T& z)
+   {
+      lanczos_initializer<lanczos17m64, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T num[17] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 2715894658327.717377557655133124376674911)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 3590179526097.912105038525528721129550434)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 2223966599737.814969312127353235818710172)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 856940834518.9562481809925866825485883417)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 229885871668.749072933597446453399395469)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 45526171687.54610815813502794395753410032)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 6884887713.165178784550917647709216424823)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 811048596.1407531864760282453852372777439)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 75213915.96540822314499613623119501704812)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 5509245.417224265151697527957954952830126)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 317673.5368435419126714931842182369574221)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 14268.27989845035520147014373320337523596)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 489.3618720403263670213909083601787814792)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 12.38941330038454449295883217865458609584)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.2183627389504614963941574507281683147897)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.002393749522058449186690627996063983095463)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1229541408909435212800785616808830746135e-4))
+      };
+      static const BOOST_MATH_INT_TABLE_TYPE(T, boost::uint64_t) denom[17] = {
+         BOOST_MATH_INT_VALUE_SUFFIX(0, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(1307674368000, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(4339163001600, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(6165817614720, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(5056995703824, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(2706813345600, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(1009672107080, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(272803210680, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(54631129553, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(8207628000, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(928095740, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(78558480, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(4899622, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(218400, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(6580, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(120, uLL),
+         BOOST_MATH_INT_VALUE_SUFFIX(1, uLL)
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+
+   template<class T>
+   static T lanczos_sum_near_1(const T& dz)
+   {
+      lanczos_initializer<lanczos17m64, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T d[16] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 4.493645054286536365763334986866616581265)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -16.95716370392468543800733966378143997694)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 26.19196892983737527836811770970479846644)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -21.3659076437988814488356323758179283908)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 9.913992596774556590710751047594507535764)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -2.62888300018780199210536267080940382158)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.3807056693542503606384861890663080735588)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.02714647489697685807340312061034730486958)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.0007815484715461206757220527133967191796747)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.6108630817371501052576880554048972272435e-5)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.5037380238864836824167713635482801545086e-8)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.1483232144262638814568926925964858237006e-13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1346609158752142460943888149156716841693e-14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.660492688923978805315914918995410340796e-15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1472114697343266749193617793755763792681e-15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.1410901942033374651613542904678399264447e-16)),
+      };
+      T result = 0;
+      for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+      {
+         result += (-d[k-1]*dz)/(k*dz + k*k);
+      }
+      return result;
+   }
+
+   template<class T>
+   static T lanczos_sum_near_2(const T& dz)
+   {
+      lanczos_initializer<lanczos17m64, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T d[16] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 23.56409085052261327114594781581930373708)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -88.92116338946308797946237246006238652361)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 137.3472822086847596961177383569603988797)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -112.0400438263562152489272966461114852861)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 51.98768915202973863076166956576777843805)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -13.78552090862799358221343319574970124948)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1.996371068830872830250406773917646121742)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.1423525874909934506274738563671862576161)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.004098338646046865122459664947239111298524)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.3203286637326511000882086573060433529094e-4)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.2641536751640138646146395939004587594407e-7)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.7777876663062235617693516558976641009819e-13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.7061443477097101636871806229515157914789e-14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.3463537849537988455590834887691613484813e-14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 0.7719578215795234036320348283011129450595e-15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -0.7398586479708476329563577384044188912075e-16)),
+      };
+      T result = 0;
+      T z = dz + 2;
+      for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+      {
+         result += (-d[k-1]*dz)/(z + k*z + k*k - 1);
+      }
+      return result;
+   }
+
+   static double g(){ return 12.2252227365970611572265625; }
+};
+
+//
+// Lanczos Coefficients for N=24 G=20.3209821879863739013671875
+// Max experimental error (with arbitrary precision arithmetic) 1.0541e-38
+// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006
+//
+struct lanczos24m113 : public boost::integral_constant<int, 113>
+{
+   //
+   // Use for long-double precision, when evaluated as an long-double:
+   //
+   template <class T>
+   static T lanczos_sum(const T& z)
+   {
+      lanczos_initializer<lanczos24m113, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T num[24] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 2029889364934367661624137213253.22102954656825019111612712252027267955023987678816620961507)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 2338599599286656537526273232565.2727349714338768161421882478417543004440597874814359063158)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1288527989493833400335117708406.3953711906175960449186720680201425446299360322830739180195)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 451779745834728745064649902914.550539158066332484594436145043388809847364393288132164411521)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 113141284461097964029239556815.291212318665536114012605167994061291631013303788706545334708)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 21533689802794625866812941616.7509064680880468667055339259146063256555368135236149614592432)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 3235510315314840089932120340.71494940111731241353655381919722177496659303550321056514776757)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 393537392344185475704891959.081297108513472083749083165179784098220158201055270548272414314)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 39418265082950435024868801.5005452240816902251477336582325944930252142622315101857742955673)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 3290158764187118871697791.05850632319194734270969161036889516414516566453884272345518372696)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 230677110449632078321772.618245845856640677845629174549731890660612368500786684333975350954)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 13652233645509183190158.5916189185218250859402806777406323001463296297553612462737044693697)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 683661466754325350495.216655026531202476397782296585200982429378069417193575896602446904762)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 28967871782219334117.0122379171041074970463982134039409352925258212207710168851968215545064)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1036104088560167006.2022834098572346459442601718514554488352117620272232373622553429728555)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 31128490785613152.8380102669349814751268126141105475287632676569913936040772990253369753962)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 779327504127342.536207878988196814811198475410572992436243686674896894543126229424358472541)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 16067543181294.643350688789124777020407337133926174150582333950666044399234540521336771876)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 268161795520.300916569439413185778557212729611517883948634711190170998896514639936969855484)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 3533216359.10528191668842486732408440112703691790824611391987708562111396961696753452085068)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 35378979.5479656110614685178752543826919239614088343789329169535932709470588426584501652577)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 253034.881362204346444503097491737872930637147096453940375713745904094735506180552724766444)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1151.61895453463992438325318456328526085882924197763140514450975619271382783957699017875304)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 2.50662827463100050241576528481104515966515623051532908941425544355490413900497467936202516))
+      };
+      static const T denom[24] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.112400072777760768e22)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.414847677933545472e22)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 6756146673770930688000.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 6548684852703068697600.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 4280722865357147142912.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 2021687376910682741568.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 720308216440924653696.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 199321978221066137360.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 43714229649594412832.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 7707401101297361068.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1103230881185949736.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 129006659818331295.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 12363045847086207.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 971250460939913.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 62382416421941.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 3256091103430.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 136717357942.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 4546047198.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 116896626.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 2240315.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 30107.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 253.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1.0))
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+   template <class T>
+   static T lanczos_sum_expG_scaled(const T& z)
+   {
+      lanczos_initializer<lanczos24m113, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T num[24] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 3035162425359883494754.02878223286972654682199012688209026810841953293372712802258398358538)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 3496756894406430103600.16057175075063458536101374170860226963245118484234495645518505519827)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1926652656689320888654.01954015145958293168365236755537645929361841917596501251362171653478)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 675517066488272766316.083023742440619929434602223726894748181327187670231286180156444871912)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 169172853104918752780.086262749564831660238912144573032141700464995906149421555926000038492)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 32197935167225605785.6444116302160245528783954573163541751756353183343357329404208062043808)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 4837849542714083249.37587447454818124327561966323276633775195138872820542242539845253171632)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 588431038090493242.308438203986649553459461798968819276505178004064031201740043314534404158)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 58939585141634058.6206417889192563007809470547755357240808035714047014324843817783741669733)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 4919561837722192.82991866530802080996138070630296720420704876654726991998309206256077395868)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 344916580244240.407442753122831512004021081677987651622305356145640394384006997569631719101)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 20413302960687.8250598845969238472629322716685686993835561234733641729957841485003560103066)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1022234822943.78400752460970689311934727763870970686747383486600540378889311406851534545789)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 43313787191.9821354846952908076307094286897439975815501673706144217246093900159173598852503)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1549219505.59667418528481770869280437577581951167003505825834192510436144666564648361001914)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 46544421.1998761919380541579358096705925369145324466147390364674998568485110045455014967149)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1165278.06807504975090675074910052763026564833951579556132777702952882101173607903881127542)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 24024.759267256769471083727721827405338569868270177779485912486668586611981795179894572115)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 400.965008113421955824358063769761286758463521789765880962939528760888853281920872064838918)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 5.28299015654478269617039029170846385138134929147421558771949982217659507918482272439717603)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.0528999024412510102409256676599360516359062802002483877724963720047531347449011629466149805)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.000378346710654740685454266569593414561162134092347356968516522170279688139165340746957511115)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.172194142179211139195966608011235161516824700287310869949928393345257114743230967204370963e-5)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.374799931707148855771381263542708435935402853962736029347951399323367765509988401336565436e-8))
+      };
+      static const T denom[24] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.112400072777760768e22)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.414847677933545472e22)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 6756146673770930688000.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 6548684852703068697600.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 4280722865357147142912.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 2021687376910682741568.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 720308216440924653696.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 199321978221066137360.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 43714229649594412832.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 7707401101297361068.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1103230881185949736.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 129006659818331295.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 12363045847086207.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 971250460939913.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 62382416421941.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 3256091103430.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 136717357942.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 4546047198.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 116896626.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 2240315.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 30107.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 253.0)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1.0))
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+
+   template<class T>
+   static T lanczos_sum_near_1(const T& dz)
+   {
+      lanczos_initializer<lanczos24m113, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T d[23] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 7.4734083002469026177867421609938203388868806387315406134072298925733950040583068760685908)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -50.4225805042247530267317342133388132970816607563062253708655085754357843064134941138154171)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 152.288200621747008570784082624444625293884063492396162110698238568311211546361189979357019)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -271.894959539150384169327513139846971255640842175739337449692360299099322742181325023644769)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 319.240102980202312307047586791116902719088581839891008532114107693294261542869734803906793)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -259.493144143048088289689500935518073716201741349569864988870534417890269467336454358361499)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 149.747518319689708813209645403067832020714660918583227716408482877303972685262557460145835)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -61.9261301009341333289187201425188698128684426428003249782448828881580630606817104372760037)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 18.3077524177286961563937379403377462608113523887554047531153187277072451294845795496072365)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -3.82011322251948043097070160584761236869363471824695092089556195047949392738162970152230254)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.549382685505691522516705902336780999493262538301283190963770663549981309645795228539620711)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.0524814679715180697633723771076668718265358076235229045603747927518423453658004287459638024)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.00315392664003333528534120626687784812050217700942910879712808180705014754163256855643360698)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.000110098373127648510519799564665442121339511198561008748083409549601095293123407080388658329)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.19809382866681658224945717689377373458866950897791116315219376038432014207446832310901893e-5)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.152278977408600291408265615203504153130482270424202400677280558181047344681214058227949755e-7)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.364344768076106268872239259083188037615571711218395765792787047015406264051536972018235217e-10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.148897510480440424971521542520683536298361220674662555578951242811522959610991621951203526e-13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.261199241161582662426512749820666625442516059622425213340053324061794752786482115387573582e-18)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.780072664167099103420998436901014795601783313858454665485256897090476089641613851903791529e-24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.303465867587106629530056603454807425512962762653755513440561256044986695349304176849392735e-24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.615420597971283870342083342286977366161772327800327789325710571275345878439656918541092056e-25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.499641233843540749369110053005439398774706583601830828776209650445427083113181961630763702e-26)),
+      };
+      T result = 0;
+      for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+      {
+         result += (-d[k-1]*dz)/(k*dz + k*k);
+      }
+      return result;
+   }
+
+   template<class T>
+   static T lanczos_sum_near_2(const T& dz)
+   {
+      lanczos_initializer<lanczos24m113, T>::force_instantiate(); // Ensure our constants get initialized before main()
+      static const T d[23] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 61.4165001061101455341808888883960361969557848005400286332291451422461117307237198559485365)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -414.372973678657049667308134761613915623353625332248315105320470271523320700386200587519147)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1251.50505818554680171298972755376376836161706773644771875668053742215217922228357204561873)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -2234.43389421602399514176336175766511311493214354568097811220122848998413358085613880612158)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 2623.51647746991904821899989145639147785427273427135380151752779100215839537090464785708684)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -2132.51572435428751962745870184529534443305617818870214348386131243463614597272260797772423)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 1230.62572059218405766499842067263311220019173335523810725664442147670956427061920234820189)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -508.90919151163744999377586956023909888833335885805154492270846381061182696305011395981929)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 150.453184562246579758706538566480316921938628645961177699894388251635886834047343195475395)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -31.3937061525822497422230490071156186113405446381476081565548185848237169870395131828731397)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 4.51482916590287954234936829724231512565732528859217337795452389161322923867318809206313688)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.431292919341108177524462194102701868233551186625103849565527515201492276412231365776131952)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.0259189820815586225636729971503340447445001375909094681698918294680345547092233915092128323)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.000904788882557558697594884691337532557729219389814315972435534723829065673966567231504429712)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.162793589759218213439218473348810982422449144393340433592232065020562974405674317564164312e-4)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.125142926178202562426432039899709511761368233479483128438847484617555752948755923647214487e-6)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.299418680048132583204152682950097239197934281178261879500770485862852229898797687301941982e-9)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.122364035267809278675627784883078206654408225276233049012165202996967011873995261617995421e-12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.21465364366598631597052073538883430194257709353929022544344097235100199405814005393447785e-17)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.641064035802907518396608051803921688237330857546406669209280666066685733941549058513986818e-23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.249388374622173329690271566855185869111237201309011956145463506483151054813346819490278951e-23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, -0.505752900177513489906064295001851463338022055787536494321532352380960774349054239257683149e-24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 113, 0.410605371184590959139968810080063542546949719163227555918846829816144878123034347778284006e-25)),
+      };
+      T result = 0;
+      T z = dz + 2;
+      for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k)
+      {
+         result += (-d[k-1]*dz)/(z + k*z + k*k - 1);
+      }
+      return result;
+   }
+
+   static double g(){ return 20.3209821879863739013671875; }
+};
+
+//
+// Lanczos Coefficients for N=32 G=2.1471552819013595581054687500000000000000000e+01
+// Max experimental error (with 40 digit precision arithmetic) 4.3871855787077623312177313715826599434111453e-39
+// Generated with compiler: Microsoft Visual C++ version 14.2 on Win32 at Oct 14 2019
+// Type precision was 134 bits or 43 max_digits10
+//
+struct lanczos32MP : public boost::integral_constant<int, 134>
+{
+   template <class T>
+   static T lanczos_sum(const T& z)
+   {
+      static const T num[32] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.5570588792269726580426965328821299006241260e+42)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.1774633762992816326945208100096848962840570e+42)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.4729248542870148408945035000721777267825674e+42)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 6.4187209355291098195390045608656819929546438e+41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.0248306413899929430368029054268103901281039e+41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 4.9257678361460200143521812997589499752976231e+40)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 9.6124719365239930504906027891035869583753288e+39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.5454747713027643957043517109001371929077089e+39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.0864696676761302003121425399683010735367223e+38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.3986590841584046388095075457448938071498037e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.3730272176307717941787236450736722205208718e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.0364763054036420066290166982737191399230330e+35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.5251577656813796428428395564637209124879141e+34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.0012588845037002389721073745460292782912025e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 5.7802279869271138404361989987596881149322644e+31)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.9402720678039082125732480764868685957396877e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.3191712125257631604053220568076491847333218e+29)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 5.2201606453728489193256459039591784247070127e+27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.8201383870559727838136908091985005180163020e+26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 5.5806105013691586921928194185346247254008596e+24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.4998261429327606587262540663611193050275961e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.5175518216952441498193267690845732518664615e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 7.1558306683405617426954019692046993902758157e+19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.2526529449739780296036175515849964203851625e+18)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.8671408513624251160128760408315369701624440e+16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.3367482193223363697833634493247948824157616e+14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.4092037586229976036163287167214501623150351e+12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.9923609136198492516415716991452463530279321e+10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.2704580842864713292739934791084236962038214e+08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 5.8637257952414489194330242306329389356743799e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.7432900891411285513294395078026439443163899e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.5066282746310005024157652848110452530069853e+00))
+      };
+      static const T denom[32] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 0.0000000000000000000000000000000000000000000e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.6525285981219105863630848000000000000000000e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.0596817613895338599493271552000000000000000e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.9028937852409282099982165606400000000000000e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.0707922020245946836608666419200000000000000e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.5477949752547197371117812531200000000000000e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 8.5189988850542311250318425141248000000000000e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.6093078815883681280561453887897600000000000e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.2136536667474513652307465210240000000000000e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.3114629767614997850763390570240000000000000e+31)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 7.4541614716906607001396551577600000000000000e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.4019376240868075016911422397440000000000000e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.2245742324696206305840307600000000000000000e+29)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.0006513636556697864066736800000000000000000e+28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.4602661104938986779113940000000000000000000e+27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.4256361393293766065270064000000000000000000e+26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.9197210605623737977801375000000000000000000e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.1458832493345014521397750000000000000000000e+24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.3605580871196332287117500000000000000000000e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 7.4359416261117272348550000000000000000000000e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.4960054586805754087500000000000000000000000e+20)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.4090257524223082475000000000000000000000000e+19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 4.8433867667953267500000000000000000000000000e+17)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.4097793282984515000000000000000000000000000e+16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.4409270792812500000000000000000000000000000e+14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 6.9491892473250000000000000000000000000000000e+12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.1400943144500000000000000000000000000000000e+11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.4803212690000000000000000000000000000000000e+09)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.4631225000000000000000000000000000000000000e+07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.0338500000000000000000000000000000000000000e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 4.6500000000000000000000000000000000000000000e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.0000000000000000000000000000000000000000000e+00))
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+   template <class T>
+   static T lanczos_sum_expG_scaled(const T& z)
+   {
+      static const T num[32] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 7.3676354398462675075959984137356365580662550e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.0303243219777652371982632367487187515581930e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 6.9695330738315109132895792451395673621363046e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.0371873841126513851737915789350097633065208e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 9.5810211111592336765499877083050083223251925e+31)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.3307571834445765987280306477823996158240302e+31)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 4.5483950445870222746510194590139013118104375e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 7.3128221728465167159919234074383914011057504e+29)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 9.8726824481851158990505892727571391497920715e+28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.1349889148269349577271512140093856701260605e+28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.1228605200219708164439121714303738845598879e+27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 9.6361256470584159095341545227609851733775758e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 7.2166868932853575755146911619588166896783547e+24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 4.7377209303689212354445666628772172811909754e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.7350675774071094836814884499810988826239303e+22)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.3912674066825924538916027148038869739001663e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 6.2420070983154004111449116807024523016395065e+19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.4700569185690640515452949188152438288912426e+18)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 8.6124656329989777592191745322776627796111867e+16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.6406132905056437989704993228158312134178284e+15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 7.0968236279962512789710882617045613206867906e+13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.6644225731453470304909038926424696324288813e+12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.3859703275819088757835059385783332958674837e+10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 5.9272583422150418041465884118526583443207265e+08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 8.8348702102467259218213323557081872404861389e+06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.1056941535328594779262418139203368431235554e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.1399784061251411774918201133708617903068477e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 9.4273820161750809875685215118516360445304050e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 6.0115080627363704378364976159119115750197259e-02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.7745767713042344487490571988087795152219347e-04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 8.2488376091888795863984895909744485000401866e-07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.1860773896913111295543391748504025973928588e-09))
+      };
+      static const T denom[32] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 0.0000000000000000000000000000000000000000000e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.6525285981219105863630848000000000000000000e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.0596817613895338599493271552000000000000000e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.9028937852409282099982165606400000000000000e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.0707922020245946836608666419200000000000000e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.5477949752547197371117812531200000000000000e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 8.5189988850542311250318425141248000000000000e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.6093078815883681280561453887897600000000000e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.2136536667474513652307465210240000000000000e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.3114629767614997850763390570240000000000000e+31)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 7.4541614716906607001396551577600000000000000e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.4019376240868075016911422397440000000000000e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.2245742324696206305840307600000000000000000e+29)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.0006513636556697864066736800000000000000000e+28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.4602661104938986779113940000000000000000000e+27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.4256361393293766065270064000000000000000000e+26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.9197210605623737977801375000000000000000000e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.1458832493345014521397750000000000000000000e+24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.3605580871196332287117500000000000000000000e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 7.4359416261117272348550000000000000000000000e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.4960054586805754087500000000000000000000000e+20)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.4090257524223082475000000000000000000000000e+19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 4.8433867667953267500000000000000000000000000e+17)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.4097793282984515000000000000000000000000000e+16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.4409270792812500000000000000000000000000000e+14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 6.9491892473250000000000000000000000000000000e+12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.1400943144500000000000000000000000000000000e+11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.4803212690000000000000000000000000000000000e+09)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.4631225000000000000000000000000000000000000e+07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.0338500000000000000000000000000000000000000e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 4.6500000000000000000000000000000000000000000e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.0000000000000000000000000000000000000000000e+00))
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+
+   template<class T>
+   static T lanczos_sum_near_1(const T& dz)
+   {
+      static const T d[31] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 7.8968008940705433227909677660515993038374841e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -5.6618604605116020762015754929520236835404324e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.8292545018854689128055824823953561237213555e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -3.5208766506452851610872857905478685024504482e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 4.4977346993761774005199362646328436255151093e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -4.0215319141694562206816207245107490261482447e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.5868485920551737806269221936902170855620396e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -1.2119342552650938943400026113911660156093453e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 4.1418202444782049081885117917390551996878611e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -1.0248307330153472190143848702750491768975848e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.8061053255438937388879028538451417962537674e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -2.2080708594510418170142862951931773430228843e-01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.8014009027542132302057253782788244298905648e-02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -9.2759167304556987616725030218164051987480377e-04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.7821648880614102293660548885638379600357589e-05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -4.3159048716588863974468231104830412871370083e-07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.8802059531699177780993451552740605512217594e-09)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -6.0864938064916182822437411537845427325953853e-12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.3077465050230400693183749778781074723249743e-15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -4.4535910089559609770590606433653482492203612e-20)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.8463914918024931651359730176750702440539677e-26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -2.6476799036488876225768641543721151210680141e-26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.9859528302828214478942827717619270410965131e-26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -2.4164337794361162374639737594212065825014909e-26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.4264219556008516021575829429243024924344353e-26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -6.3654171220500680155015450276084381767112451e-27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.1771337070979387873887155215691051891368210e-27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -5.6130349210382862255475637378026742528052158e-28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.0357425223049510242618626197816013695138258e-28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -1.2237222565117372586662393874248709023486029e-29)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 6.9653890134419774710417169916706146555543512e-31))
+      };
+      T result = 0;
+      for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k)
+      {
+         result += (-d[k - 1] * dz) / (k * dz + k * k);
+      }
+      return result;
+   }
+
+   template<class T>
+   static T lanczos_sum_near_2(const T& dz)
+   {
+      static const T d[31] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 6.8235732906799716623552488416933899152528589e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -4.8923760814221749411260475309979161560716608e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.5806466857096723284428938485933849993255433e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -3.0423661676922237999255010522403805001149858e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.8864627302775745934819737805015890258069096e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -3.4749790611725489418874785394046879079002711e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.2352787155916216728704971718263237763940956e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -1.0472243539148225143721882968062403836164182e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 3.5789194097878442125894349247978066638013227e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -8.8554944097961585263202464603716331582929738e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.5606436359298279012809323203777498460831161e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -1.9079793884371809023191793438331090550554931e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.5565785753912199592703963702155052413697331e-01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -8.0152581402976896653242934862478024763161144e-03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.4040502318727807490297102100258877023641629e-04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -3.7293447818191967510645955265996052825799609e-06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.4887668661450911754046983982188022868005334e-08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -5.2592989400365993333512441603746877766052195e-11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.9941084528494632503325323388230135305735007e-14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -3.8483184600922127060811720536956793306527275e-19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.5954546450654998035263505446322855520450213e-25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -2.2878426485811911877035106634321308368820032e-25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 2.5801420414749176901982573044724995471338101e-25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -2.0880244059892646868604082519013410844174147e-25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.2325617535559095736858057307295434296584568e-25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -5.5003147275337403154295953682157801293504851e-26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 1.8812468002260686540475204400230633058447779e-26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -4.8501862565143035234095815929073455137122638e-27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 8.9497824575117543406738759847704395400692055e-28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, -1.0574102876284982539299549303708483236373651e-28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 134, 6.0187464606086614102031360043044718659169199e-30)),
+      };
+      T result = 0;
+      T z = dz + 2;
+      for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k)
+      {
+         result += (-d[k - 1] * dz) / (z + k * z + k * k - 1);
+      }
+      return result;
+   }
+
+   static double g() { return 2.1471552819013595581054687500000000000000000e+01; }
+};
+
+//
+// Lanczos Coefficients for N=35 G=2.96640371531248092651367187500000000000000000000000000e+01
+// Max experimental error (with 50 digit precision arithmetic) 67eps
+// Generated with compiler: Microsoft Visual C++ version 14.2 on Win32 at Oct 14 2019
+// Type precision was 168 bits or 53 max_digits10
+//
+struct lanczos35MP : public boost::integral_constant<int, 168>
+{
+   template <class T>
+   static T lanczos_sum(const T& z)
+   {
+      static const T num[35] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.17215050716253100021302249837728942659410271586236104e+50)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.51055117651708470336913962553466820524801246971658127e+50)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.40813458996718289733677017073036013655624930344397267e+50)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 5.10569518324826607478187974291222641098997506635019681e+49)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.34502197565331471178368569687788687058240547971732391e+49)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.74311603169690571192608960963509140372217014888512918e+48)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 4.50656021978234091874071935392175934984492682009447097e+47)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 6.12703102551730381018400796362603958419580969330315139e+46)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 7.02844698442195350077632196816248435420923619452768200e+45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 6.90106767379334717236568166816961185224083190775430842e+44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 5.86371531667026447746284883480888667804130713757839681e+43)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 4.34808948517797782155274346690360992144536507118093783e+42)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.83232124439938458545786668616393415008373341980153072e+41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.62895707563068512468013948922815298700909218398406635e+40)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 8.30384063116420066671650072267242339695473078925159324e+38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.76258309689585811716178198120267186946262194080905971e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.51837231299916455171135124843484994848995300472356341e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 5.46324357690180919340289798257560253430931750807924001e+34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.75333853376321853646128997503611223620394342435525484e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 5.01719517877315910652307531002686423847077617217874485e+31)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.27861878894319497853745513558138184450369083409359360e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.89640024726662067702004632718605032785787967237099607e+28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 5.81537701811791870172286588846619085013138846074815251e+26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.03090758312551459302562064161308518889144037164899961e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.60538569869661647274451913615710409703905629234367906e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.18176163448730621246454091850022844174919234685832508e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.56586635256765282348264053213197702964352373258511008e+19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.58289895656990946427745668670352144404744258615044371e+17)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.19373478903102411154024309088124853938046967389531861e+15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.54192605870424877025476980158698548681325282029269310e+13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 8.73027427579217615249706012469272147499107562412573337e+10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.82675918536460865549992482360500962016208597062710654e+08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.21869956201943834772161655315196962519434419814106818e+06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.50897418653428667959996348205296461689142907811767371e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.50662827463100050241576528481104525300698674060984055e+00))
+      };
+      static const T denom[35] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 0.00000000000000000000000000000000000000000000000000000e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 8.68331761881188649551819440128000000000000000000000000e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.55043336733310191803732770947072000000000000000000000e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 6.55728779174162547080350866368102400000000000000000000e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 7.37352350419052295388404251629977600000000000000000000e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 5.72117566475005542296335706764492800000000000000000000e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.28417720643003773414159612967554252800000000000000000e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.45822739485943139719482682477713244160000000000000000e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 5.16476527817201997988283152951021977600000000000000000e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.49225481668254064104679479029764121600000000000000000e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.57726463942545496998486904826347776000000000000000000e+35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 7.20859297660335343156864734965859840000000000000000000e+34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.23364307820330543590375511999050240000000000000000000e+34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.80750015058176473779293385245398400000000000000000000e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.28183125026789051815954180232544000000000000000000000e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.49437224233918151570015089338400000000000000000000000e+31)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.37000480501772121324931003824000000000000000000000000e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.96258640868140652967646352465000000000000000000000000e+29)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.41894262447739018035536664650000000000000000000000000e+28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 8.96452376168568744680811480000000000000000000000000000e+26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 4.94875410890088264440962800000000000000000000000000000e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.38478815149246067334598000000000000000000000000000000e+24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.00124085806115519088380000000000000000000000000000000e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.65117470518809938644000000000000000000000000000000000e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.15145312544238764840000000000000000000000000000000000e+20)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.12192419709374919000000000000000000000000000000000000e+18)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 7.22038661704031100000000000000000000000000000000000000e+16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.40979763670090400000000000000000000000000000000000000e+15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.29191290647440000000000000000000000000000000000000000e+13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.04437176604000000000000000000000000000000000000000000e+11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.21763644400000000000000000000000000000000000000000000e+09)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.60169360000000000000000000000000000000000000000000000e+07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.51096000000000000000000000000000000000000000000000000e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 5.61000000000000000000000000000000000000000000000000000e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.00000000000000000000000000000000000000000000000000000e+00))
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+   template <class T>
+   static T lanczos_sum_expG_scaled(const T& z)
+   {
+      static const T num[35] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.84421398435712762388902267099927585742388886580864424e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.28731583799033736725852757551292030085556435695468295e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.84381150359300352571680869181416248982215282642834936e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 6.68539753215772969226355064737523321566208288321687448e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.76117184320624276162478300964159399462275652881271996e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.59183627116994441494601110756468114877940946273012852e+35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 5.90089018057779871758440184258134151304912092733579104e+34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 8.02273473587728940068021671629793244969348874651645551e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 9.20304883823127369598764418881022021049206245678741573e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 9.03625836242722113759123056762610636251641913153595812e+31)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 7.67794913334462808923359541498599600753842936204419932e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 5.69338859264140114791649895977363900871692586779302150e+29)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.70864158121145435408364940074910197916145829346031858e+28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.13295647753179115743895667847873122731507276407230715e+27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.08730493440263847356723847541024859440843056640671533e+26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 4.92672649809905793239714364398097142490510744815940192e+24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.98815678372776973689475889094271298156568135487559824e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 7.15357141696015228406471054927723105303656292491717836e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.29582156512528703674984172534752222415664014582498353e+20)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 6.56951562180494343732211791410530161839249714612303326e+18)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.67422350715677024140556410421772283993277946880053914e+17)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.79254663081905790190270601146772274854974105071798035e+15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 7.61465496276608608941993297108655885737613121720232292e+13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.34987044168298086318822469739196823360923972361455073e+12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.10209211537761991333937729340544738747931371426736883e+10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.85679879496413826670691454915567101976631415248412906e+08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.35974553231926272707704478737590721340254406209650188e+06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.38204802486455055334129565820015244464343854444712513e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.87247644413155087645140975008088533286977710080244249e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.01899805954981363917258740277358024893572331522514601e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.14314215799519834172753514406176454576793263619287700e-02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 5.01075867159821346256470334018168931185179114379271616e-05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.59576526838074751422330690168945437827562833198707558e-07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.28525092722679899458094768960179796663588010298597603e-10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.28217919006153582429216342066702743329957749672852350e-13))
+      };
+      static const T denom[35] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 0.00000000000000000000000000000000000000000000000000000e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 8.68331761881188649551819440128000000000000000000000000e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.55043336733310191803732770947072000000000000000000000e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 6.55728779174162547080350866368102400000000000000000000e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 7.37352350419052295388404251629977600000000000000000000e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 5.72117566475005542296335706764492800000000000000000000e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.28417720643003773414159612967554252800000000000000000e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.45822739485943139719482682477713244160000000000000000e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 5.16476527817201997988283152951021977600000000000000000e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.49225481668254064104679479029764121600000000000000000e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.57726463942545496998486904826347776000000000000000000e+35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 7.20859297660335343156864734965859840000000000000000000e+34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.23364307820330543590375511999050240000000000000000000e+34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.80750015058176473779293385245398400000000000000000000e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.28183125026789051815954180232544000000000000000000000e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.49437224233918151570015089338400000000000000000000000e+31)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.37000480501772121324931003824000000000000000000000000e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.96258640868140652967646352465000000000000000000000000e+29)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.41894262447739018035536664650000000000000000000000000e+28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 8.96452376168568744680811480000000000000000000000000000e+26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 4.94875410890088264440962800000000000000000000000000000e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.38478815149246067334598000000000000000000000000000000e+24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.00124085806115519088380000000000000000000000000000000e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.65117470518809938644000000000000000000000000000000000e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.15145312544238764840000000000000000000000000000000000e+20)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.12192419709374919000000000000000000000000000000000000e+18)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 7.22038661704031100000000000000000000000000000000000000e+16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.40979763670090400000000000000000000000000000000000000e+15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.29191290647440000000000000000000000000000000000000000e+13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.04437176604000000000000000000000000000000000000000000e+11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.21763644400000000000000000000000000000000000000000000e+09)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.60169360000000000000000000000000000000000000000000000e+07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.51096000000000000000000000000000000000000000000000000e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 5.61000000000000000000000000000000000000000000000000000e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.00000000000000000000000000000000000000000000000000000e+00))
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+
+   template<class T>
+   static T lanczos_sum_near_1(const T& dz)
+   {
+      static const T d[34] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.09112391094335813989230740596164619994797033481760301e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -1.11095925828443504625574261745581427703630213518975734e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 5.25795762399049096970854782036824945808150003653799701e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -1.53596813364794430843820749839089482856771473577902136e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.10150518856225197104044336968686219568570379161186763e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -4.59440015012604275008985164760189204399872934212169290e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 5.17182126100715726914905437099855137991832224176746144e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -4.52194070233963020921586697582404279809725757428225907e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.11287192546142126817144783716567250328231623970392395e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -1.70029010284498269942986238607675315541449827223720491e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 7.39359986548869257712075354365607803246217579350731025e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -2.55857186796151318525331772210231419636656738702520247e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 7.01976508569781091139272219093293962106866776273944401e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -1.51622799316222576708968190643735578161547893435503117e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.55114022296440557292153472011659421232773792851704649e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -3.29558714084043876803654097222727620781593122323144986e-01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.20655790191462561334686083455624901268509187198531392e-02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -2.29211265190736317625627743320462821391020598683096969e-03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.16547271274032555838193953745182811226836340887412893e-04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -4.04158977282328622262713955181985365200737836471868621e-06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 9.04099527601588222217706879074903022432460969180041885e-08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -1.21026124816545340223909137077288908237190834054935310e-09)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 8.73486546143800890651761116982457576405090186184403710e-12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -2.92426051924806467732549205594664201603409972582813132e-14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.61340208721806452778722682494918504979435178283255061e-17)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -1.13517996614037348212434679983945901825382670014683797e-20)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 4.61930266547148210568279523485628689044657261784716591e-25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -5.78463508004708787795311937422590618909194917033730955e-31)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -1.53568640059658459444865728826184250691297909350787934e-35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 6.63117406343686364701920733651409741863929155565374940e-36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -2.02296711810469513023726896410540806344003955071812851e-36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 4.05776322342042086937257880311088879198393056129493081e-37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -4.82527152907979058393765521600344474439209706209233775e-38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.61571352467214817635971061532522193500863154360283722e-39))
+      };
+      T result = 0;
+      for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k)
+      {
+         result += (-d[k - 1] * dz) / (k * dz + k * k);
+      }
+      return result;
+   }
+
+   template<class T>
+   static T lanczos_sum_near_2(const T& dz)
+   {
+      static const T d[34] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.27149725743552824677345467452765724462183747425698430e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -1.29461157973340118022513089366929246812794440622918275e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 6.12714892558448280578038020250503421879861075137953016e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -1.78987853703364598882843888232934449281930468883391335e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.61421402429854740596701737352164170551274801368708941e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -5.35389897687788587032725281528384185518833066402901114e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 6.02677338784735277115375432621012998338558552597357336e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -5.26946128083650646734645560602832582368091536233949979e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.62745979285730759140267927796734683888575236461558969e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -1.98136451866684089001192332403279162096332022571108845e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 8.61583350640418693864271497678443168377071451407567658e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -2.98152856924573421857895007425890467500099537012952122e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 8.18020021813066494304354702578430478815286552616366363e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -1.76687516020609325102781997617812558189956529947937455e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 2.97286840137911020382328323869139629696357829352821391e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -3.84037960234558373817068181823488833809395626348103188e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.73663296826451629159939759241902446349258313114071094e-01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -2.67102106498038196040637483025426329160024817197530409e-02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.35813663599770253165594840156807550072235435724240491e-03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -4.70970369202279764117806847443483943084782006868895857e-05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.05355593279987378383061490338957570599931723523376630e-06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -1.41032914996100466638712258076005313289749145071459453e-08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 1.01788232911919897659739133018267424364933824143275367e-10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -3.40766909510419913528326529229511125941552363401838743e-13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 4.21073243637136845906400015214174112719748429942427344e-16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -1.32283620509730411652267827642614145629073466029279697e-19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 5.38291811911040907926983774874091831690977569145002154e-24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -6.74089126429842876230950047383862474772290970041867579e-30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -1.78955023078122126762117283369038212754061385626732316e-34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 7.72737133764019622888917725972972138033556721960526187e-35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -2.35738316863436492576730648996735973692694426493195922e-35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 4.72855077059130427852097715321796484769785970590691282e-36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, -5.62293563001680479553446157798018614684701661703654843e-37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 168, 3.04811629504314504274190599430387363985052709041515655e-38)),
+      };
+      T result = 0;
+      T z = dz + 2;
+      for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k)
+      {
+         result += (-d[k - 1] * dz) / (z + k * z + k * k - 1);
+      }
+      return result;
+   }
+
+   static double g() { return 2.96640371531248092651367187500000000000000000000000000e+01; }
+};
+
+//
+// Lanczos Coefficients for N=48 G=2.880805098265409469604492187500000000000000000000000000000000000e+01
+// Max experimental error (with 60-digit precision arithmetic) 51eps
+// Generated with compiler: Microsoft Visual C++ version 14.2 on Win32 at Oct 14 2019
+// Type precision was 201 bits or 63 max_digits10
+//
+struct lanczos48MP : public boost::integral_constant<int, 201>
+{
+   template <class T>
+   static T lanczos_sum(const T& z)
+   {
+      static const T num[48] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.761757987425932419978923296640371540367427757167447418730589877e+70)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 8.723233313564421930629677035555276136256253817229396631458438691e+70)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 6.460052620548943146316510839385235752729444155384745952604400014e+70)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.118620599704657143233902039524163888476114389296433891234019212e+70)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.103553323924588863191816202847384353588419783622786374048756587e+70)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.051624469576894078907076790635986076815810433950937821174281248e+69)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 6.865434054315747674202246332480484800778071304068935338977820344e+68)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.291785980379681713553231795767203835753576510251486784293089714e+68)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.073927196464385740270105346713079967925505577692095446860826790e+67)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.884317172328855613403642857232246924724496526520223674336243586e+66)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.515983058669346491005379681336434957516572863544374020968683717e+65)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.791988252541273516986153564408477102509671668999707480365384945e+64)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.645764905652320236264233988360776875326874810201273735655153182e+63)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.144135487589921315512939394666974184673239886993573956770438389e+62)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.444700846549614719681016920231266383188819427952261902403138865e+61)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.721099093953481665535866508692670759355705777392277743203856663e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.100969797434901880312682514502493221610943693861105392844971160e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 6.418121506159806547634040503980950792234471035467217702752406105e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.417864259432558812733518752689742288284271989351444645566759428e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.665995533734965936996397899459612023184583125575089834552055942e+55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 7.444766925649844009950058690449625999301860892596426461258095232e+53)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.053637791492838551734963920042182131006240650838206322215619662e+52)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.150696853422753584935226676401667305978026730065639035499393518e+51)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.985976091763077924792684854305586783380530313659602423780141188e+49)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.269589095786672590317833654141210781129738119237951536741077115e+48)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.718300118825405526804849893058410300716988331091767076237827497e+46)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.001037055130874457401651655102738871459032839441218104652569066e+45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.475842513986568687160423191409256650108932454810648362428602348e+43)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.620452049086499203878684285356863241396518483154492676811559133e+41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.169661026157169583693125067814111812572434991018171004040405784e+40)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.227918466522161929152413190031319328201533237960827483146218740e+38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.876388843752351291646654793076860108915313255758699513365393870e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 6.145947758366681136606104191450792163942386660344907590963820717e+34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 8.853323303407534484800459250019301328433169196161471441696806506e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.154628006575221227908667538321556179086649067527404327882584768e+31)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.357526820024103486396860374714568600536209103260198100884104997e+29)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.431529899588725297356982438015035066854198997921929156832870645e+27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.345565129287503320724079046959642760096964859126850291147857935e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.118851309483567225684739040233675455708538654675741148330404763e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 8.153371780240325463304870847387326315142505274277395976930776452e+20)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.146212685927632120682088036018035709941745020823689824280902727e+18)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.771109638413640784841091904266004758198074452790973613270876444e+16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.247775743837944205683004431867637625466576857881195465700397478e+14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.570311375510395966207715903995528566489264305503840005145629111e+11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.307932649387240491969419239876926639445902586258953887216911993e+09)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.743144608535924824275750439447323876880302369055576390115394778e+06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.749690888961891063146468955091435916957208840312184463551812828e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.506628274631000502415765284811045253006986740609938316629929233e+00))
+      };
+      static const T denom[48] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 0.000000000000000000000000000000000000000000000000000000000000000e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.502622159812088949850305428800254892961651752960000000000000000e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.430336111272256671478593169569751383305061494947840000000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.920361290698585974808779016476219830728024276336640000000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 6.149178946896205138947217427059336370288899808821248000000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.374105269656119699331051574067858017333550280343552000000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.521316226597066883749849655326023294027593332332429312000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.808864152650289891915479515152146571014320216782405632000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 7.514810409642252571378917003183814999063638859346214912000000000e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.583350992233550434239775839017811699814141926043903590400000000e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 7.478403249251559174520099458337662519939088809134875607040000000e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.848344883280695333961708798743230793633983609036568330240000000e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.943873277267014936040757307088314776495222166971439104000000000e+55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 7.331069721888505257142927693659482094449571844495257600000000000e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.196124539826947758881834650235619760202156354268084224000000000e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.723744838816127002822609734027860811982593574672547840000000000e+53)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.205691767196054136766333529400075228162139411801728000000000000e+52)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.517213632743192166819003098472340901249838381523200000000000000e+51)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.571722144655713179046526371841394014407124514352640000000000000e+50)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.359512744028577584409389641902976782871564427046400000000000000e+49)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.949188285585060392916084953872833077002135851920000000000000000e+48)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.452967188675463645529736303316005271151737332000000000000000000e+47)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 9.790015208782962556675223159728484084908850744000000000000000000e+45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.970673071264242753610155919125826961862567840000000000000000000e+44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.299166890445957751586491053313346243255473500000000000000000000e+43)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.652735578141047520337049888545244673386975000000000000000000000e+42)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 7.508428802270485256066710729742536448661900000000000000000000000e+40)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.093294777021479729147119238554967297499000000000000000000000000e+39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.155176275192359061296447275633302204250000000000000000000000000e+38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.907505708457079284974986712721395225000000000000000000000000000e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.195848283940498442888394846136646210000000000000000000000000000e+35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.305934675041764670409270520636101000000000000000000000000000000e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 8.238840089027488915014959267151000000000000000000000000000000000e+31)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.846167161648076059624793804150000000000000000000000000000000000e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.707826341119682695847826052600000000000000000000000000000000000e+28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 6.648183019818072129964867660000000000000000000000000000000000000e+26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.059080011923383455919277000000000000000000000000000000000000000e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.490144286132397218940500000000000000000000000000000000000000000e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.838362455658776519186000000000000000000000000000000000000000000e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.970532718044669378600000000000000000000000000000000000000000000e+19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.814183952293757550000000000000000000000000000000000000000000000e+17)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.413370614847675000000000000000000000000000000000000000000000000e+15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 9.134958017031000000000000000000000000000000000000000000000000000e+12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.765795079100000000000000000000000000000000000000000000000000000e+10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.928125650000000000000000000000000000000000000000000000000000000e+08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.675250000000000000000000000000000000000000000000000000000000000e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.081000000000000000000000000000000000000000000000000000000000000e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.000000000000000000000000000000000000000000000000000000000000000e+00))
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+   template <class T>
+   static T lanczos_sum_expG_scaled(const T& z)
+   {
+      static const T num[48] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.775732062655417998910881298714821053061055705608286949609421120e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.688437299644448784121592662352787426980194425446481703306505899e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.990941408817264621124181941423397180231807676408175000011574647e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 9.611362716446299768312931282360230566955098878347512701289885826e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.401071382066693821667231534775770086983519477562699643517826070e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 9.404885497858970433702192998314287586471872015950314081905843790e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.115877029354588030985670444733795075439494699793733843615128537e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.981190790128533233774351539949086864384527026303253658346042487e+55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 6.391693345003088328615594164751621620795026048184784616056424156e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 8.889256530644592752851605934648543064680013184446459552930302708e+53)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.083600502252557317792851907104175947655615832167024966482957198e+53)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.168663303100387254423547467716347840589509950430146037235024663e+52)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.123598327107617380847613820395680616677588511868146055764672247e+51)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 9.689997752127767317102012222013845618089045780981297513260591263e+49)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 7.534390868711924145397558028431517797916157184545344400315049888e+48)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.304302698603539256283286371502868034443493795813215278491516590e+47)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.393109140624987047793401361048831961769792029208766436336102130e+46)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.978018543190809154654104033779556195143800802618966016721119650e+45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.053360999285885098804414279382371819392475408561904784568215676e+44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.134477518753880004346650767299407142912151189519394755303948278e+42)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.294423222517027804991661400849986263936601088969957809227734095e+41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 9.411090410120803602405769061472811786006792830932395177026805674e+39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.546364324011365762789375386661337991434000702963811196005801731e+38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.228448949533845774618310075362255075191314754073111861819975658e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.912781600174900095022672513908490962899309128877584272045832513e+35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.145953154225327686809754524860534768156895534588187817885425867e+34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.085123669861365984774838320924008647858451270384142925874188908e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 7.630367231261397170650842427640465271470437848007390468680241668e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.732182596346604787991836614669276692020582495778773122326853797e+29)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.604810530255586389021528105443008249789929772232910820974558737e+27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 6.866283281281868197964883431828004811500103664332499479032936741e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.194674953754173153419535571352963617418336620849047024493757781e+24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.894136566262225941799684575793203365634052117390221232065529506e+22)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.728530091896234109430773225830735206267902257956559214561779937e+20)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.558479853180206010560597094150305393424259777860361999786422123e+18)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.183799294403182487629551851184805610521945574359855930862189385e+16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.411871423439005125979602342436157376541872925894678545707600871e+14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.146934230284030660663814250662713645615827253848318877256260252e+12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.448218665084135299794121636822853382005896647323977605040284573e+10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.512810104228409918190743070957013357446861162954554120244345275e+08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.586025460907685522041021408846741988415862331430490056017676558e+06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 8.540359114012197595748944623835295064565126012703153392373623351e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.845554430040583564794301575257907183920519062724643766057340299e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.408536849955106342184570268692357634552350288861587703063273018e-01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.030953654039823541442226125506893371879437951634029024402619056e-04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 8.454172918244607114802676127860508419821673596398248024962237789e-07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.155627562127299657410444702080985966726894475302009989071093439e-09)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 7.725246714864934496649491688787278190129598018071339049048385845e-13))
+      };
+      static const T denom[48] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 0.000000000000000000000000000000000000000000000000000000000000000e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.502622159812088949850305428800254892961651752960000000000000000e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.430336111272256671478593169569751383305061494947840000000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.920361290698585974808779016476219830728024276336640000000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 6.149178946896205138947217427059336370288899808821248000000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.374105269656119699331051574067858017333550280343552000000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.521316226597066883749849655326023294027593332332429312000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.808864152650289891915479515152146571014320216782405632000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 7.514810409642252571378917003183814999063638859346214912000000000e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.583350992233550434239775839017811699814141926043903590400000000e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 7.478403249251559174520099458337662519939088809134875607040000000e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.848344883280695333961708798743230793633983609036568330240000000e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.943873277267014936040757307088314776495222166971439104000000000e+55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 7.331069721888505257142927693659482094449571844495257600000000000e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.196124539826947758881834650235619760202156354268084224000000000e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.723744838816127002822609734027860811982593574672547840000000000e+53)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.205691767196054136766333529400075228162139411801728000000000000e+52)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.517213632743192166819003098472340901249838381523200000000000000e+51)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.571722144655713179046526371841394014407124514352640000000000000e+50)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.359512744028577584409389641902976782871564427046400000000000000e+49)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.949188285585060392916084953872833077002135851920000000000000000e+48)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.452967188675463645529736303316005271151737332000000000000000000e+47)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 9.790015208782962556675223159728484084908850744000000000000000000e+45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.970673071264242753610155919125826961862567840000000000000000000e+44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.299166890445957751586491053313346243255473500000000000000000000e+43)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.652735578141047520337049888545244673386975000000000000000000000e+42)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 7.508428802270485256066710729742536448661900000000000000000000000e+40)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.093294777021479729147119238554967297499000000000000000000000000e+39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.155176275192359061296447275633302204250000000000000000000000000e+38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.907505708457079284974986712721395225000000000000000000000000000e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.195848283940498442888394846136646210000000000000000000000000000e+35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.305934675041764670409270520636101000000000000000000000000000000e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 8.238840089027488915014959267151000000000000000000000000000000000e+31)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.846167161648076059624793804150000000000000000000000000000000000e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.707826341119682695847826052600000000000000000000000000000000000e+28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 6.648183019818072129964867660000000000000000000000000000000000000e+26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.059080011923383455919277000000000000000000000000000000000000000e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.490144286132397218940500000000000000000000000000000000000000000e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.838362455658776519186000000000000000000000000000000000000000000e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.970532718044669378600000000000000000000000000000000000000000000e+19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.814183952293757550000000000000000000000000000000000000000000000e+17)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.413370614847675000000000000000000000000000000000000000000000000e+15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 9.134958017031000000000000000000000000000000000000000000000000000e+12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.765795079100000000000000000000000000000000000000000000000000000e+10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.928125650000000000000000000000000000000000000000000000000000000e+08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.675250000000000000000000000000000000000000000000000000000000000e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.081000000000000000000000000000000000000000000000000000000000000e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.000000000000000000000000000000000000000000000000000000000000000e+00))
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+
+   template<class T>
+   static T lanczos_sum_near_1(const T& dz)
+   {
+      static const T d[47] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.059629332377126683204423480567078764834299559082175332563440691e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.045539783916612448318159279915745234781500064405838259582295756e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.784116147862702971548198855631720823614071322755242269800139953e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.347627123899697763041970836639890836066182746484603984701614322e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.616287350264343765684251764154979472791739226517501453422663702e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -3.713882062539651653939339395399443747287004395732955159091898814e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.991169606573224259776909844091992693404451938778998047720606365e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -3.317302161605094814956529918647229867233820698992970037871348037e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.160243421312714521088457044577429625205805822189897013706603525e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.109943233027050100899811890306430189301581767622560123811853152e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.510589694767723034579229465791750718722450232983242500655372350e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.447631000703120050516586541372187152390222336990410786008441418e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.650513815713423478665128697883383003943391843803280033790640056e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -7.169833252147741984016531016457108860830636610643268300442548571e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.082891222574188256195988224106955541928146669677565424595939508e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.236107424816170540654753273736991964308279435358993150196240041e-01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.042295614972976540486053879488442847688158698802215145729595300e-02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -6.301008161384761854991230670333450694872613042265540662425668275e-04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.626174700692043436308812511757112824553679923076031241653340508e-05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -7.165638597797307942127436742547456896168876912136407736672893749e-07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.193760947891421842393017150194414897043594152709554867681454093e-08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.102566205604210639065160857917396944102487766555058309172771685e-10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.915816623470797626925445072607835810426224865943397673652473644e-13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -8.588275837841705058968991523347781566219989845111381889185487327e-16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.200550301285945062259329336559146630395284987411539369061121774e-19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -3.164333226683698411437894680594408940426530663957731548446585176e-23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.066415481671710192926882432742434212829003971627792457166443068e-28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.794259516500627365643093960688415401054083199354112116216326548e-35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -4.109766027021453750770079684473469373477285891593627979028234104e-35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 7.857040454431507009464118652247309465880198950544005451066913133e-35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.257636833252205356462338019252188768182918234805529456629813332e-34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.657386968948568677903872677704817552898314429680193647771915640e-34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.807368757318279512579151153998249666772948741065806312921477647e-34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.661046240741398691824399424582067048482718145278248186045239803e-34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.310274358393495831279259654715581878034928245769119610060724565e-34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 8.979289812994200254512860775692570111131240734486735844065571645e-35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -5.374132043246630393307108400571746261019561481928368054130159659e-35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.807680467889122570534300256450516518962725443297886143108832476e-35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.273791157694681089776609329544693948790210894828257493359951461e-35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.971177216154470328027539744763226999793762414262864963697237346e-36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.645869582759689501568146144102914403686604774258048281344406053e-36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.533836765077295478897031652308024155740827573708543095934776509e-37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.011071482407693628614243045457397049948479637840391111641112292e-37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.753334959707221495336088007359122169612976692723773645699626150e-38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -2.217604773736938924265403811396189809599754278055061061653740309e-39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.819104328189909539214493755590516594857915205552841395610714917e-40)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -7.261124772729210946163851510369531392121538686694430629664292782e-42))
+      };
+      T result = 0;
+      for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k)
+      {
+         result += (-d[k - 1] * dz) / (k * dz + k * k);
+      }
+      return result;
+   }
+
+   template<class T>
+   static T lanczos_sum_near_2(const T& dz)
+   {
+      static const T d[47] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.201442621036266842137537764128372139686555918574926377003612763e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.185467427150643969519910927764836582205108528009141221591420898e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.424388386017623557963301151646679462091516489317860889362683594e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.527983998220780910263892115033927387104053611029099941633323011e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.966432728352315714505545454293409301356907573727621630702827634e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -4.210921746972897898551337991192707389898034825880579655985363009e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.525319492963037163576188790739239848749059077112768508582824310e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -3.761266399512640929192286468240357629226481512485264527650043412e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.449355108314973517543246836489412427594992113516547680523282212e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.258490177973741431378782429416242097479994678322390199981700552e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.114255088752286384038861754183366335220682008583459292808501983e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.641371685961506906939690430062582517060728808639566257675679493e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.139072742579462987548668350779672609568514018384674745960251434e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -8.129392978890804438983060711164783076784089453197491087525720250e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.227817717944841986447189375517242505918979312023367060292099051e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.401539292067249253713639886818857395065226008969910929456090178e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.181789081601278618540976740818676551399023595924451938057596056e-01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -7.144290488450459735914078985115746320918090890348935029860425141e-03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.977643331768050273059868974450773270172308183228656321879824795e-04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -8.124636941696344229278652214634921673116603924841964381194849043e-06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.353525462444406600575359080915245707387262742058104197063680358e-07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.250125861423094782405286690199652039727315544398975014264972834e-09)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.573714720964717327652547152474097356959063887913062262865877352e-12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -9.737669879005051560419153179757554889911318336987864449783329044e-15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 4.762722217636305077074994367900679148917691897585712642440813437e-18)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -3.587825185218585020252537180920386716805319681061835516115435092e-22)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.209136980512837161314713015292452549173388035330975386269996826e-27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.034390508507134900778125110328032318737425888723900242108805840e-34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -4.659788018772143666295222723749466460348336784193790467337277007e-34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 8.908571128342935499766722474863105091718059244706787068658556651e-34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.425950044120254934054607924023969978647876123112048584684333719e-33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.879199908120536747953526966437055347446296944118172532473563579e-33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -2.049254197314637745167349860869170443784687973315125511356920644e-33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.883348910945891785870183207161008885784794173754432580579430117e-33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.485632203001929498321635338807138918181560966989477820879657556e-33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.018101439657813295290872898460623215815148336073781084176896879e-33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -6.093367832078140478972419022586567008505333455627897676553352131e-34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 3.183440545955440848970303491445824299419388286256245840846211512e-34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.444266348988579122529259208173467560400718346248315966198898381e-34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.636484383471871096369253024129613184534143941833907586683970329e-35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.866141116496477515961611479835778926021343627571438400431425496e-35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 5.140613382384541819628458619521408963917801187880958447868987984e-36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -1.146386132171160390143187663792496413753249459594650450672610453e-36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 1.987988898740147227778865012441676866493607979490727350027458052e-37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -2.514393298082843730831623322496784440966181704206301582735570257e-38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, 2.062560373914843383483799612278119836498689222815662595453851079e-39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 201, -8.232902310328177520527925464546117674377821202617522000849431630e-41)),
+      };
+      T result = 0;
+      T z = dz + 2;
+      for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k)
+      {
+         result += (-d[k - 1] * dz) / (z + k * z + k * k - 1);
+      }
+      return result;
+   }
+
+   static double g() { return 2.880805098265409469604492187500000000000000000000000000000000000e+01; }
+};
+//
+// Lanczos Coefficients for N=49 G=3.2804746093749997726263245567679405212402343750000000000000000000000000000e+01
+// Max experimental error (with 60-digit precision arithmetic) 88eps
+// Generated with compiler: Microsoft Visual C++ version 14.2 on Win32 at Oct 14 2019
+// Type precision was 234 bits or 73 max_digits10
+//
+struct lanczos49MP : public boost::integral_constant<int, 234>
+{
+   template <class T>
+   static T lanczos_sum(const T& z)
+   {
+      static const T num[49] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.5742499367008530642617319352897520430205552639474773193534726699460038382e+74)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.2055424563420473601452029826557352738661904429902299059433513914586136617e+74)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.5124573975150897396579361228988665521507891014129938036244581220575769357e+74)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 6.7657855450073472861630911067774749012357295936579551712546801770340228765e+73)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.2200724511833181761435003548793565030399736349888521665887428093215263908e+73)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.6969626159645181170657767707096364240775930310958541253756412108457464465e+72)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1902838064351166646672468793217979804852505454197638767497901741630038659e+72)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.0815524946284433112181691476757266928589723434617417902816279882371678020e+71)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.1085775474754412572785597234367295850853434122501232697548485520290211685e+70)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 4.0248876219420480494671692552535249842631934230477107608175338135254767453e+69)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 4.5717898581583284547576613790182065259217990496576104453319232531339965508e+68)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 4.5987266955225124754687270016251985476100549398788271466921127242855554305e+67)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 4.1277201593916609119851488898621364059725185338025069187337522019022532875e+66)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.3266912844842724918464413240523721967983751112927460422203771012324285814e+65)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.4198349306520385923755583127019190414798256355752152907538684107889754415e+64)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.5954968135971263467860541616149005468520952700568675174669869313790120813e+63)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 9.5697573028906337479684490638442403255222113759866980140004921288934014321e+61)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.2372180596212313667398562038281895205587396825353276904411403952354592724e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.6216537416683580103634264243351068913266542152026155538733152213171424662e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.2028581946420676660634538276758371308595650705510961727364638531545389749e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.0668609223671045472881034712995505846341571161239968651357297157517601241e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.9620881267196496193861934343921326919697524102893094861578977849944522047e+55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 6.9917155089797622879653341069010820156774380191279115491781432309218621096e+53)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.2942244374439765758128985411022615606270110470067503605960457871147797553e+52)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 6.9351028342882568351470704633625779062510316389795468890729515726996746376e+50)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.9314927110707228066333377498237626208657080992885612416826068446390297282e+49)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 4.9556005176089621449765653988254594966772984328873034691437246673533838584e+47)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1708002669765411191695114973458120651885979389757503801447241827647515479e+46)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.5453624823926493383313636717841737625222638948016893410076575426986147237e+44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.0870291142516923896770486348199039577071847823857246263136765980806245584e+42)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 9.3337301613565742543387644582305705841930917569470575861418313137426853827e+40)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.5696392889303372910143506267477452989689410812923616782357472172107995484e+39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.4143864855807616500285749805611035801672647319221651520900664580210701417e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.3883950248556863481116504212968387826172322376709179509012607292972789664e+35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 4.3257340722619328574784440823494550029955992275874284892851081786012219555e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.0054658629154523660536922265411423770787857332470130847913952020455172951e+31)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.2273347597734780854875327656763513602785317406227796368685036961474823856e+29)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 4.9014441058506987415445336961216002315976811002826148787399813116200761040e+27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 4.1007719003538290551470147047960192204273669359908829249030378418530058831e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.0380905019192393560853564871253022486270254732200016399586810852416299561e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.9744635849298784873006356360567530952404226257040467086536310864153303851e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1124649237555162417911032704785227088470234269296071198905173077670702197e+19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.3521744565441850034376761928380748678988834367585778746740882700228177944e+16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.1551192264984335079683102449711150606277601324509245213720618349409077054e+14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 7.0649463728846790219460420909345995584550543072052058591106589782466481621e+11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.8110794685236845669275412185521099716923991533427218655037515888279356458e+09)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.4051945147325155571782612757500183884572379142638708146516926708747795902e+06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 4.1761279721833493440329993975995822357104129877086617643903445974526391316e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.5066282746310005024157652848110452530069867406099383166299235756022800280e+00))
+      };
+      static const T denom[49] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 0.0000000000000000000000000000000000000000000000000000000000000000000000000e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.5862324151116818064296435515361197996919763238912000000000000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1477605944577727245447890951265834050463405543784448000000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.3368731677410579748749120694395208342752220248276992000000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.9393177179482022750532799808826502923430631529093529600000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.5873212662073383100750664140824866318496576298496819200000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.7087596791971826323557398537439095283663043689996772966400000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 8.8537931401160691803777386867476912131700643521105494016000000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.7128473077968876977396389430116077066613422855709615718400000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.2893230704461912298064838143702096489032830938340968366080000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.7731846263715878554484243293204825543527859328977818943488000000000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 9.4350612763444239870720412999269509820736318433853587128320000000000000000e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.0384549286435665533353268142058310243161527793802332119040000000000000000e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.8399900970142989644612517467287880620408209836099149824000000000000000000e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 6.3548923093755049924589156254733610823950920495095216128000000000000000000e+55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 9.2977252822627446721481004001665655765203461552290590720000000000000000000e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.2090496144637581445624377322208214384344648810140669440000000000000000000e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.4036595841089057320815648092220077464036379804960768000000000000000000000e+53)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.4604307712625044108337677046126892768963323598980608000000000000000000000e+52)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.3661432041590027825770657688785384893903477321470720000000000000000000000e+51)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1520697686278361431114988925105292244781602931070400000000000000000000000e+50)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 8.7781340723597395269058455794580578514153013123200000000000000000000000000e+48)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 6.0542743368034560471670911883883927910588971816800000000000000000000000000e+47)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.7852178643724903498642955979619870805662919592000000000000000000000000000e+46)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.1476757456360244186066663869698554305163293290000000000000000000000000000e+45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1067024107708881097170625529475996208174256000000000000000000000000000000e+44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.1816971152081755906884039315242368042580680000000000000000000000000000000e+42)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.2046914254271439983058171150950882746907200000000000000000000000000000000e+41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 8.5226232704255673172404214340314876574740000000000000000000000000000000000e+39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.9917039581671863252346910306123579600000000000000000000000000000000000000e+38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 9.5279926429774219665504424895636324120000000000000000000000000000000000000e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.7496375812101278379807519908356136800000000000000000000000000000000000000e+35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 7.1781895168846844604663013761970710000000000000000000000000000000000000000e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.6915825748773446395251490146656000000000000000000000000000000000000000000e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.5888455419743269266732720488720000000000000000000000000000000000000000000e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 6.8324723604341765969313138528000000000000000000000000000000000000000000000e+28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1625859075857974372785469560000000000000000000000000000000000000000000000e+27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.7594478264056101488213120000000000000000000000000000000000000000000000000e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.3541746402920221829579200000000000000000000000000000000000000000000000000e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.7645128331397711271280000000000000000000000000000000000000000000000000000e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.8231991756227354271000000000000000000000000000000000000000000000000000000e+19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.4784681412721648000000000000000000000000000000000000000000000000000000000e+17)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.8427136416481320000000000000000000000000000000000000000000000000000000000e+15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1374881704208000000000000000000000000000000000000000000000000000000000000e+13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.6720141346000000000000000000000000000000000000000000000000000000000000000e+10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.1948624000000000000000000000000000000000000000000000000000000000000000000e+08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 6.1833200000000000000000000000000000000000000000000000000000000000000000000e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1280000000000000000000000000000000000000000000000000000000000000000000000e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.0000000000000000000000000000000000000000000000000000000000000000000000000e+00))
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+   template <class T>
+   static T lanczos_sum_expG_scaled(const T& z)
+   {
+      static const T num[49] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 8.9156595384723483714761513394165493705512008185104458104037189919966679583e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.2490942626049052041642905803851633038401948356209065994820093902482046488e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 8.5657016133969059292054137486140786946523144967749946090276991389460410256e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.8317575261281828541202228096164333127703313535243593976139496326255603885e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.2573232282907489549580534670684496645767812633106925447384772399512629009e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.2264367876545276188760221330510623567338280567044843125670581811561508361e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 6.7410929642927466039608438519399985289266866350365951941371580436768272283e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1788733746089745519939950216688781077254011132768568000829003039800512115e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.7605221646260701306188822826505483714178735327624200723152581930359377597e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.2794682649344687478785548483237660272987192396957769664741689026760236827e+55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.5892026994266264487972781655291611074377224857532819461836222961458821278e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.6044581976409422084009086165534449955654966215396670231211076839220955529e+53)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.3377067867856641370165698166594859838986332949917530009978864573093452852e+52)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.8840494251009843798733373985085724953611000664053469151896413377742842585e+51)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.3704573764322216880093728898018690177362850852138123977146826586562660042e+50)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 9.0359898089375286965109471568127438755772335943188122764617864358438172366e+48)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.4197682330664983610360781372995395147813463692379312665516728111546651975e+47)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.9660635239520142135892297007271080519825235074724441273950199516718744758e+46)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.4847561142331378363753305417832438611221296838300212519621989387291450611e+45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 6.8123071733863185211372790750342775813125583218947155817719674827525929182e+43)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.8695828952857913310728321803468643286198192850402657393713980287261259638e+42)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1112155264857128661506293440611411838336453876178977662636328219208269490e+41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.9597114546218224309028736968589856884375435031334606638164700453351137400e+39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.2993187112308342042984815542969104496107563160266146124117192158716725839e+38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.9276492438289459104440745719026053099029450534209231660211458499968839130e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.0938880168568707970634270396301729019623679984385010064117584299386152912e+35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.8065713069852021979452626742757704686014267992443726831364663812595589478e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 6.6307492378187334600766084298235996134621924808224715558467640454423842655e+31)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.4415490682866089784509877074414842364885644695603000622810515902853301434e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.8810050162690958474575145223002401297790616292489104417882204295223485358e+28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.2860958353933214242194744963395870718749107497800918932121607454081905640e+26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 8.8895474422826652624342608217034044478811180021465482602156553101973142851e+24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.3673716858987747316948988327383411119224741422002091782489841976044254452e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.9189949269921720477131833122497011042624119182630703457459218878350720360e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.4498506458943304056122167501858896499220570899589497703614276271780187559e+19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.8348122127750881334333964077955476539118633228361300065573128691903485670e+17)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.9604661829895068017545272035886457795302072787311442846001622570781400887e+15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.7759001843251065234667097315555616424286286440771094985162292676933917344e+13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.3224448199826427582356965293979283708473565146649764333289536983716495991e+11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.7206022964144885856033111994076522875074747824871090843993137657458226608e+09)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1182242847179807470291498763391918222721736346452719834560856782062915656e+07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 6.3003709115482840946768994349442745995208542698397935766566883071074706882e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.0311683127686139178455785110448360190741004055855567244689436514834230540e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.2205374026276431316033131273698903101132908812758212963153267146702515001e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 4.0011852660581895977871209152278420195617235126960126683426738428884540341e-03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.0256927799097601645189517227865464454408483715314872385869625463116763013e-05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.9285092060573954544191464750091257510108951419853791428165851425157303961e-08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.3651222287552713546296738256776548189076669986821606599921179638781057448e-11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.4196122080178359418232367999588103764109880361922878363699332724809241837e-14))
+      };
+      static const T denom[49] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 0.0000000000000000000000000000000000000000000000000000000000000000000000000e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.5862324151116818064296435515361197996919763238912000000000000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1477605944577727245447890951265834050463405543784448000000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.3368731677410579748749120694395208342752220248276992000000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.9393177179482022750532799808826502923430631529093529600000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.5873212662073383100750664140824866318496576298496819200000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.7087596791971826323557398537439095283663043689996772966400000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 8.8537931401160691803777386867476912131700643521105494016000000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.7128473077968876977396389430116077066613422855709615718400000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.2893230704461912298064838143702096489032830938340968366080000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.7731846263715878554484243293204825543527859328977818943488000000000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 9.4350612763444239870720412999269509820736318433853587128320000000000000000e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.0384549286435665533353268142058310243161527793802332119040000000000000000e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.8399900970142989644612517467287880620408209836099149824000000000000000000e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 6.3548923093755049924589156254733610823950920495095216128000000000000000000e+55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 9.2977252822627446721481004001665655765203461552290590720000000000000000000e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.2090496144637581445624377322208214384344648810140669440000000000000000000e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.4036595841089057320815648092220077464036379804960768000000000000000000000e+53)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.4604307712625044108337677046126892768963323598980608000000000000000000000e+52)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.3661432041590027825770657688785384893903477321470720000000000000000000000e+51)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1520697686278361431114988925105292244781602931070400000000000000000000000e+50)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 8.7781340723597395269058455794580578514153013123200000000000000000000000000e+48)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 6.0542743368034560471670911883883927910588971816800000000000000000000000000e+47)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.7852178643724903498642955979619870805662919592000000000000000000000000000e+46)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.1476757456360244186066663869698554305163293290000000000000000000000000000e+45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1067024107708881097170625529475996208174256000000000000000000000000000000e+44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.1816971152081755906884039315242368042580680000000000000000000000000000000e+42)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.2046914254271439983058171150950882746907200000000000000000000000000000000e+41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 8.5226232704255673172404214340314876574740000000000000000000000000000000000e+39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.9917039581671863252346910306123579600000000000000000000000000000000000000e+38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 9.5279926429774219665504424895636324120000000000000000000000000000000000000e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.7496375812101278379807519908356136800000000000000000000000000000000000000e+35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 7.1781895168846844604663013761970710000000000000000000000000000000000000000e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.6915825748773446395251490146656000000000000000000000000000000000000000000e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.5888455419743269266732720488720000000000000000000000000000000000000000000e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 6.8324723604341765969313138528000000000000000000000000000000000000000000000e+28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1625859075857974372785469560000000000000000000000000000000000000000000000e+27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.7594478264056101488213120000000000000000000000000000000000000000000000000e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.3541746402920221829579200000000000000000000000000000000000000000000000000e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.7645128331397711271280000000000000000000000000000000000000000000000000000e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.8231991756227354271000000000000000000000000000000000000000000000000000000e+19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.4784681412721648000000000000000000000000000000000000000000000000000000000e+17)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.8427136416481320000000000000000000000000000000000000000000000000000000000e+15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1374881704208000000000000000000000000000000000000000000000000000000000000e+13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.6720141346000000000000000000000000000000000000000000000000000000000000000e+10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.1948624000000000000000000000000000000000000000000000000000000000000000000e+08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 6.1833200000000000000000000000000000000000000000000000000000000000000000000e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1280000000000000000000000000000000000000000000000000000000000000000000000e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.0000000000000000000000000000000000000000000000000000000000000000000000000e+00))
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+
+   template<class T>
+   static T lanczos_sum_near_1(const T& dz)
+   {
+      static const T d[48] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.2066789802575522178795921101394468758895980798225454578416417743837821182e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.3679788352265125219923749199991620615257401271523573821302279091870986385e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 7.2630033804072373059579276357751429378169881873880556882995810292143631169e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -2.3999752086438541157776701982236284193725611536088710297195418612889088941e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.5326869500703014940743489551921365917396663139743104045090175695793718397e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -9.4539806536100390983482685579769998888148275478188901957443850396223701663e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.2418837249375022042463276831798225069762119451024109889652570545798197307e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.2837532371348753406818677898802253115337338144774680681639085300947433821e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.0603676137809014970843333435453530863140601935101507289758344098164636049e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -7.0675156715558786066521224677848991893948220792765278914746791001795702147e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.8231576762102015440131857562883207655276091648820750106248419664382342083e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.6828357670521487851037941818117892204609675060095269337474530867886953446e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 6.0263919393474265394410446439494942658409182482953883911882462037294240391e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.7511174204844870012138672336839720481677091590654128683087419414952818657e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 4.1077240937707245791059934044373222445269304780721564415689327491376493334e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -7.7197427650993388314150434222790763404096237849031957731092258677118877326e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1502942251829477374710555866529647619927300737021040120015632037419548655e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.3407293979752550880132165447474755706150471817851620226242890535888257338e-01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.2014334746887994911502478644617408322636134206225589060774099980181312765e-02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -8.0983646402105726518672426329015155996093741444426226630025345020847577111e-04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.9942365899792195557178345302806016444352718230344395806792868608352214871e-05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.3916756170744060855799456788870481671060079696580348774412746337324507629e-06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.2738029264164285805306112157985005833945884241358728352406636162060451936e-08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -4.9005795832591317070122324350352498562565929180970558213118848371143071658e-10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 4.3120237284050523317140903263269508807725654665206264201337566990649593815e-12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.9993164488488861127293338637233872747923249255635013388317575640760246175e-14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 4.1770960183589659510713725797228496911736699917131125983799031646762143273e-17)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -3.1067143632180728240506803448567684891294208768806045480286272494772691950e-20)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.6244126131167038529019905678720925754781858101865433373489388749513540167e-24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.2602412034992451089948288841723108481473094784377158526788906759478344724e-28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 8.5993275050503412644261961442095022244184843038273154020407386192200117900e-35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.2376677581089123203915935849311668028430409001498177367770610457728550321e-39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.8150848887085059253468109780286976776338724012461857375172227849044365287e-39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.2888861291942792803542790121202831584212092799440963290014968720997192671e-39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -2.4367686092860277330824120317504561350242498766190734227637416697402218133e-39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.1658834966582889258321173900424691594425653659844978485212529673045052341e-39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.6078489664179099912530462853749930668959707942650569176553871936075352345e-39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.0044570187922899426305396174281740469543589839974788550682447627990764739e-39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -5.3214978442929458907632954943316397146183013077035413667972521651417588659e-40)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.3990788346383540827394552555896039808285381860296208830197355311239959128e-40)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -9.1813962257175782149431101470253920074573257556345440519764098954533396958e-41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.9566302522237219982311281591833653462640003193980940062047608523626590962e-41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -7.8844939069206979681852040267695059179818896523029249336074241598129744909e-42)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.6980186103098555864348162964443149317288303456071195638226831779183346735e-42)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -2.8409438292612321309493446423416582883045091540877596567806910261300252610e-43)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.4666144269083503254700296220598377304876489203081567665937809718753144311e-44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -2.7449599736044707057960973836294763832382889203992176649603299199814964095e-45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.0585685375038567471031307628591396658405283305367035292669018178549132199e-46))
+      };
+      T result = 0;
+      for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k)
+      {
+         result += (-d[k - 1] * dz) / (k * dz + k * k);
+      }
+      return result;
+   }
+
+   template<class T>
+   static T lanczos_sum_near_2(const T& dz)
+   {
+      static const T d[48] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.5455231550124674608383465879384903101217726809855880053735498558660305251e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.7521171744934997797979463716947798398649024826461953154035391579443199892e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 9.3025071978608000907597512615615521968983853964414599121560447447486249179e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -3.0739055847506874449724863962235222139048946552417933333489374601444889442e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 7.0863054140081769874319573695951392605490718603916106954837774653056576623e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.2108726717088904191265369690298547113580473039391314603986085479556111007e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.5906136463190712486212821488571957306185167770225864012898706881699647057e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.6442404200085453327213398272100872399623441451383083438265316066112956103e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.3581264998698427315063870744999865373965234956609066658837559718999590062e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -9.0521251281527290170664891261612911437995934455165647349853355253750334406e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 4.8967279703383588010975605180679227794424995039989024281878608594596616855e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -2.1553882073152030175586351692198830408611546985761579133373632331779244638e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 7.7186463308194716629084448574149234823489365098510570780593191406061889318e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -2.2428438423008152181399734545002360362921592139304278927551479335858821905e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.2612026936693838529789647834479279275034238291000514930718615542291190074e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -9.8875023012785484029602598574637362767234771045911074782572204578687659312e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.4733051533871237880957666174363507890599952187881138769651021452363258297e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.7172158984110335489611392604457344891052843492969255546784144895328933329e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.5388046735862609465152559757953131111281278387717331973511139237319990770e-01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.0372443934101018493930850177650436102881381002613480220638309361418767946e-02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.1158470789748281012838916430380981653860595791320888251473386188428788856e-04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.7824681838708087799263224394519010740357745634535755030787340328399772549e-05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 4.1931104382411821412587448903202613576618187938526144451753089437172395491e-07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -6.2766977322268088075311831528842893348256386710249195361734612266778385323e-09)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.5228711415779960574453455948991424203497366984285083000319325448210101974e-11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -2.5607389508299290889393825247382548268608977769597750095981719736417860627e-13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 5.3500547558276404981577111880189245551703390604657164900460067017086475257e-16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -3.9791021994420737378470356651659599587167405408055854179971153565586792084e-19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 7.2037883058679724499875763987161800762132311085398211645162684109748694340e-23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.6141260374761318937819974670878746263129124551434880143657761001893177100e-27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.1014080790364138694339981796904397090336135156681914457153169895058123962e-33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.5852138055486955162695207029733124482316515915389725207819834510328826882e-38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -2.3247738377057606447050864939101938086522392428747461590714144146282468974e-38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.9316218892795919921760137631186915684395320376859960566984260379803979907e-38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -3.1210308380902232855988541317886447706766253774127605015790322866153349557e-38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.7740792289514179382145837836403663560484901236914958039358936821942590582e-38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -2.0593445713551373294655454085927889987266290706104795764516423812212247302e-38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.2865158059079907658671256163529513022184187924172645112729579745062723961e-38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -6.8158128816897517506937531950420472376185024126168447501964316612370015014e-39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.0727575024490003112672747176557026577347452778581212406977128868690751231e-39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.1759598612683119428775753540097890056929269067220807101660487076215190882e-39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 3.7868733858667171123449703661037140974108364228765817302050018596960416788e-40)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -1.0098516753892371349956889909483048597911093401064123370095186647248754503e-40)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 2.1748345026411581847490576071466694584307900894689508331424519370338054748e-41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -3.6387013796128814207293408288388785778364579569320260571422484577307186443e-42)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 4.4400648009494470795051094944915668879009266928618607576647564429190022802e-43)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, -3.5157645638963794722990984515235056341682398223940346512667816730324057574e-44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 234, 1.3558222299776027787073219176369904651832196778690432544150792644775402371e-45)),
+      };
+      T result = 0;
+      T z = dz + 2;
+      for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k)
+      {
+         result += (-d[k - 1] * dz) / (z + k * z + k * k - 1);
+      }
+      return result;
+   }
+
+   static double g() { return 3.2804746093749997726263245567679405212402343750000000000000000000000000000e+01; }
+};
+//
+// Lanczos Coefficients for N=49 G=3.71521093750000019895196601282805204391479492187500000000000000000000000000000000000e+01
+// Max experimental error (with 80-digit precision arithmetic) 75eps
+// Generated with compiler: Microsoft Visual C++ version 14.2 on Win32 at Oct 14 2019
+// Type precision was 267 bits or 83 max_digits10
+//
+struct lanczos49MP_2 : public boost::integral_constant<int, 267>
+{
+   template <class T>
+   static T lanczos_sum(const T& z)
+   {
+      static const T num[49] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.29576393886533812647621748658593518049105182771886345672193119325886860615058992916e+76)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.64940250521075704286553287922703978233859608760738220959805633167660346858918484441e+76)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.02782279850582131264593341856583603623569135771086732311690891701018783486399941058e+76)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 4.17871318833644489595452604622172623859528919270761702889241650479860350523603645576e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.24636895901125366174317752785594004344350462222105593541765135970641727807408046603e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.90766536403132277814150094353285923029162708480029761430241108404154368124040257524e+74)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 5.52382781721986299602475060387708982171655203328511435511051797995280492002324724681e+73)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 8.78482374388380268613213967834073614067861524793728730151201542394918426634868617345e+72)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.19325027080949586393337406155391099309209314019751861163367432285571050834050337943e+72)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.40545316209557907826875120370637029196186181048557227564363347693674382156389673345e+71)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.45248231502915687322615277256109191586795311001308546524559632502753988355826682144e+70)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.32951710710760475384871665492267398285929602882057694753684715739127717537388087360e+69)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.08609708232067139682194681883946299264352243218047148918541516101215386723695461807e+68)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 7.96790018517492120048938623906554309076682107791064003018940091271134763465693455777e+66)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 5.27669033307366420506859833929956397578574575080825866111910129757118415016658467329e+65)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.16802337748974823514819525636942825363065912689755393017268041605495575074123213602e+64)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.73054387508326490801862749035024819220968371854706600225017512476962193917082134622e+63)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 8.62670382432299595501509896985706425528571034019439577742070022359804568860138431456e+61)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.93419603580003232059946064747952976400826625336761312144282727389088893514776127326e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.64477326525726493380322761443767318183513031346169727378679051953394311858102484110e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 6.31417565379195208375864005040359979626430954027274059125918083665481151874801228147e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.22873281009357235993917586746434823288058696112725892939606733669981526181084161579e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 7.24038151344262567906410045463097784963500265667230009248051943941184141216283364012e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.16635103397331843098281133679963613292528445793288854356269441338108669168034969473e+53)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 5.97226028792130808404381304085761534201244857265870272466382244177818968609788744866e+51)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.51722539705401822010051258989781033530766592277336923172687967760117181597042914505e+50)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.55143196851124103497589961680541188447723645252871343011474640057780989215029733411e+48)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 7.65631576916353367608977102104279419518759334245125488959476099210969778356845251386e+46)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.51913643147679636800192101181821796326331285929097206716389984328795132228290343736e+45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.77142070954017798440735921701401232362942654167866941640116269309928860707230400223e+43)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 4.64265304588830405590756890757870027959619641212378439580733250347485559404826031214e+41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 7.12961287129418300922993605074391681508051626956297216905205033442654279681009631622e+39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.00163852645278376379452857266851549886004284453902427442045925921205957134756527439e+38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.28416298426892934885339736163488241290345416925540130172490965458139411097784230624e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.49793255972439978183906387866659603599388803095306163216192230005161964280456557158e+34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.58404837985235629013707612365235872533571223333496498253968477010731743022987544752e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.51210388163173191310089232642285522934883375636207281562370177051035472857070373332e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.29625175202138639315345810129285907904834629385738665013524881366645746417930602439e+28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 9.91704411637684940906309546543695853685028152118727394684725500498007979899474115290e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 6.71980627815396304296720837491060731114276254036666247979635295719640774180255608217e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.99515302992882524356421852289147703799628458429164679118485650618041455793969699036e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.05962638033903929635201902285319054754141795004681756534441119215276710860621598251e+19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 9.06860641169958199340995275230206293988239276251216776246763641876943705626715807705e+16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.34257282855413383182163862298720605042203946165367698145431759335580579509759239742e+14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.00325103633255410612780052993328410422609156975902055798191507344081921284741604327e+12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.35516908008075882088679988477934347017452660082246021362543874768562840957846903854e+09)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 4.05605466237751558310956675128455566243720955874966620350919363272463056561354608608e+06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 4.55729572460925281137543520027396380407277254872226907448088245735142585109299314309e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.50662827463100050241576528481104525300698674060993831662992357634350984153163470001e+00))
+      };
+      static const T denom[49] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.58623241511168180642964355153611979969197632389120000000000000000000000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.14776059445777272454478909512658340504634055437844480000000000000000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.33687316774105797487491206943952083427522202482769920000000000000000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.93931771794820227505327998088265029234306315290935296000000000000000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.58732126620733831007506641408248663184965762984968192000000000000000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.70875967919718263235573985374390952836630436899967729664000000000000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 8.85379314011606918037773868674769121317006435211054940160000000000000000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.71284730779688769773963894301160770666134228557096157184000000000000000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.28932307044619122980648381437020964890328309383409683660800000000000000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.77318462637158785544842432932048255435278593289778189434880000000000000000000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 9.43506127634442398707204129992695098207363184338535871283200000000000000000000000000e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.03845492864356655333532681420583102431615277938023321190400000000000000000000000000e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.83999009701429896446125174672878806204082098360991498240000000000000000000000000000e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 6.35489230937550499245891562547336108239509204950952161280000000000000000000000000000e+55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 9.29772528226274467214810040016656557652034615522905907200000000000000000000000000000e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.20904961446375814456243773222082143843446488101406694400000000000000000000000000000e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.40365958410890573208156480922200774640363798049607680000000000000000000000000000000e+53)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.46043077126250441083376770461268927689633235989806080000000000000000000000000000000e+52)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.36614320415900278257706576887853848939034773214707200000000000000000000000000000000e+51)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.15206976862783614311149889251052922447816029310704000000000000000000000000000000000e+50)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 8.77813407235973952690584557945805785141530131232000000000000000000000000000000000000e+48)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 6.05427433680345604716709118838839279105889718168000000000000000000000000000000000000e+47)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.78521786437249034986429559796198708056629195920000000000000000000000000000000000000e+46)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.14767574563602441860666638696985543051632932900000000000000000000000000000000000000e+45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.10670241077088810971706255294759962081742560000000000000000000000000000000000000000e+44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 5.18169711520817559068840393152423680425806800000000000000000000000000000000000000000e+42)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.20469142542714399830581711509508827469072000000000000000000000000000000000000000000e+41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 8.52262327042556731724042143403148765747400000000000000000000000000000000000000000000e+39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.99170395816718632523469103061235796000000000000000000000000000000000000000000000000e+38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 9.52799264297742196655044248956363241200000000000000000000000000000000000000000000000e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.74963758121012783798075199083561368000000000000000000000000000000000000000000000000e+35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 7.17818951688468446046630137619707100000000000000000000000000000000000000000000000000e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.69158257487734463952514901466560000000000000000000000000000000000000000000000000000e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.58884554197432692667327204887200000000000000000000000000000000000000000000000000000e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 6.83247236043417659693131385280000000000000000000000000000000000000000000000000000000e+28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.16258590758579743727854695600000000000000000000000000000000000000000000000000000000e+27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.75944782640561014882131200000000000000000000000000000000000000000000000000000000000e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.35417464029202218295792000000000000000000000000000000000000000000000000000000000000e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.76451283313977112712800000000000000000000000000000000000000000000000000000000000000e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.82319917562273542710000000000000000000000000000000000000000000000000000000000000000e+19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.47846814127216480000000000000000000000000000000000000000000000000000000000000000000e+17)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.84271364164813200000000000000000000000000000000000000000000000000000000000000000000e+15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.13748817042080000000000000000000000000000000000000000000000000000000000000000000000e+13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 5.67201413460000000000000000000000000000000000000000000000000000000000000000000000000e+10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.19486240000000000000000000000000000000000000000000000000000000000000000000000000000e+08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 6.18332000000000000000000000000000000000000000000000000000000000000000000000000000000e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.12800000000000000000000000000000000000000000000000000000000000000000000000000000000e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.00000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00))
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+   template <class T>
+   static T lanczos_sum_expG_scaled(const T& z)
+   {
+      static const T num[49] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 9.49663610130791477461794140374370924490696733744664264226063545477852907120064438588e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.20884482942845999689198014205795770851399772847436497410154319183860398480228326286e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 7.53289916571146966947513241858798999095967787802671792160665282347073321227016292403e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.06257315326410705497495763375336857281692495321204603919284336971479478405381409540e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 9.13462097275260056500457419367381935327442299676685171001942731892832408882413435566e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.13102394952914002112762425649207244062991186339070382885956481064589709031894816496e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 4.04840581629048620249901745346405131124091439055732548308528857701167494671648257347e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 6.43838524961944675350746734141447316445830054880306039896637689653198992735066081474e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 8.74531483688910159100344151068655208511626316424159676205726034341092475816888011372e+55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.03005469109920428385867124264753643595038929217266678155910599078268836953793159656e+55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.06452229265586101928934888140259774581544836837635812825070642317924068191237940651e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 9.74401260751298616807064335204160985098707747263556384563576228484205922370857356950e+52)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 7.95999059097413995107763881990067736638605879036860399501004480843044798852321320153e+51)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 5.83966309607370356019329894907872727851559431468853382195539375506355518522739451561e+50)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.86727909378079977412627692901220876068535926169729765468023963613209750668440883454e+49)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.32183997980385285815563935626564558737112327901896765866420315909089479889407291483e+48)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.26831322790199691523763382147990685271332413931335425536077401693909941536685446004e+47)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 6.32249937786475248948857177694117967417864070990756190329454700663693499608768713815e+45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.88336686819032307424839603734550094343459546588744595045643380205822126447806151375e+44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.20545206582813581050133859680698140274276251798965738445951215893805514854794850980e+43)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 4.62765065960304045423639870153223988753806599339881709607153712409175486794708548715e+41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.63343521375027791107490012004281169470903074417529835343633992756599689706467597925e+40)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 5.30646566133119269769508008116142168214781437395136629206311256865360022042754477332e+38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.58771569575797497748917749020901655508364490119697350339089287796185236358536233400e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 4.37706135782308791418825498038425839394113136784263252755599976807797063043875082698e+35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.11197240850069894333209760920904406397403024207197696391699562264322296386093323413e+34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.60283960927607800898139439849090533043340726395143638152077844277751805149166560973e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 5.61130330576422804633963440554474730419413739922460725405112412454286488484955915987e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.11337300300297295349076762512699923957438723580465440290334845396273762855836733517e+29)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.03117042948259288566605349078528499682057378893001882806984505986948136392761267006e+27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.40259403730882930955675549420130062238621449273398874217078083754343032954759973357e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 5.22528347572098799721775967384397848588784390912022136506439711506219967445623919686e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 7.34099499566403754037791880900467520578107411723617564672664393961433945628291065109e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 9.41161286449337414692992004461766142962293572495919749372515938105183883550234862604e+19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.09783271453440804906045665973485276329744852249747400433246982560607811629926185500e+18)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.16094688076417849092104554198103013111536406662498981965117749909832209236913802539e+16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.10821885688578986410930893219376699456504867926107715594671444282949767588694287037e+14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 9.50021127722497072888981489155684575207215375480643952454970468046331143014884622646e+11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 7.26818800470068614566377728536610325478326870447541587095650095821101649087210816040e+09)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 4.92493678677258766132448688907920434402513619957710479626424529957236460471189038381e+07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.92804216541904692956935385209461325937556277824668580633404375808334363503194457710e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.50949734377247428538055873924894146321959030826140132714559567319426159642629912422e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 6.64636917688205569668044105440719648394808067896062765005278597960400006426062506946e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.44976703261974330359141562652121211268881081847095890846270752149427888286399621821e-02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 7.35281305841345486358892992557075736755186129730528304574018484234880523171404766251e-05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.72610018227274377132777187985570646349538821991325846732587180123971090415405994340e-07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.97267688814850268231161594533176277702963907108885229111755006417082297177116403628e-10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.34003577384307789433517516041141801840291757339440089597599691127216013708701908122e-13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.83710441782049075320423070384744844199992659460213011403809803120117400852034616312e-16))
+      };
+      static const T denom[49] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.58623241511168180642964355153611979969197632389120000000000000000000000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.14776059445777272454478909512658340504634055437844480000000000000000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.33687316774105797487491206943952083427522202482769920000000000000000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.93931771794820227505327998088265029234306315290935296000000000000000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.58732126620733831007506641408248663184965762984968192000000000000000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.70875967919718263235573985374390952836630436899967729664000000000000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 8.85379314011606918037773868674769121317006435211054940160000000000000000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.71284730779688769773963894301160770666134228557096157184000000000000000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.28932307044619122980648381437020964890328309383409683660800000000000000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.77318462637158785544842432932048255435278593289778189434880000000000000000000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 9.43506127634442398707204129992695098207363184338535871283200000000000000000000000000e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.03845492864356655333532681420583102431615277938023321190400000000000000000000000000e+57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.83999009701429896446125174672878806204082098360991498240000000000000000000000000000e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 6.35489230937550499245891562547336108239509204950952161280000000000000000000000000000e+55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 9.29772528226274467214810040016656557652034615522905907200000000000000000000000000000e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.20904961446375814456243773222082143843446488101406694400000000000000000000000000000e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.40365958410890573208156480922200774640363798049607680000000000000000000000000000000e+53)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.46043077126250441083376770461268927689633235989806080000000000000000000000000000000e+52)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.36614320415900278257706576887853848939034773214707200000000000000000000000000000000e+51)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.15206976862783614311149889251052922447816029310704000000000000000000000000000000000e+50)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 8.77813407235973952690584557945805785141530131232000000000000000000000000000000000000e+48)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 6.05427433680345604716709118838839279105889718168000000000000000000000000000000000000e+47)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.78521786437249034986429559796198708056629195920000000000000000000000000000000000000e+46)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.14767574563602441860666638696985543051632932900000000000000000000000000000000000000e+45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.10670241077088810971706255294759962081742560000000000000000000000000000000000000000e+44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 5.18169711520817559068840393152423680425806800000000000000000000000000000000000000000e+42)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.20469142542714399830581711509508827469072000000000000000000000000000000000000000000e+41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 8.52262327042556731724042143403148765747400000000000000000000000000000000000000000000e+39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.99170395816718632523469103061235796000000000000000000000000000000000000000000000000e+38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 9.52799264297742196655044248956363241200000000000000000000000000000000000000000000000e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.74963758121012783798075199083561368000000000000000000000000000000000000000000000000e+35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 7.17818951688468446046630137619707100000000000000000000000000000000000000000000000000e+33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.69158257487734463952514901466560000000000000000000000000000000000000000000000000000e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.58884554197432692667327204887200000000000000000000000000000000000000000000000000000e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 6.83247236043417659693131385280000000000000000000000000000000000000000000000000000000e+28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.16258590758579743727854695600000000000000000000000000000000000000000000000000000000e+27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.75944782640561014882131200000000000000000000000000000000000000000000000000000000000e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.35417464029202218295792000000000000000000000000000000000000000000000000000000000000e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.76451283313977112712800000000000000000000000000000000000000000000000000000000000000e+21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.82319917562273542710000000000000000000000000000000000000000000000000000000000000000e+19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.47846814127216480000000000000000000000000000000000000000000000000000000000000000000e+17)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.84271364164813200000000000000000000000000000000000000000000000000000000000000000000e+15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.13748817042080000000000000000000000000000000000000000000000000000000000000000000000e+13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 5.67201413460000000000000000000000000000000000000000000000000000000000000000000000000e+10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.19486240000000000000000000000000000000000000000000000000000000000000000000000000000e+08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 6.18332000000000000000000000000000000000000000000000000000000000000000000000000000000e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.12800000000000000000000000000000000000000000000000000000000000000000000000000000000e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.00000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00))
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+
+   template<class T>
+   static T lanczos_sum_near_1(const T& dz)
+   {
+      static const T d[48] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.36662594316736437928923771651218082870790219434510733129873815200968646566980996339e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -1.76780165965526893166944674250172218113345269194305352999222919039854748751783233101e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.07970572889193090835848021094044050788957851893559287421136980839960026782217427894e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -4.14103116540076985021820709941614153683990156820041738016476143763552291310864305462e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.11895235901890827822967425840835669339942717903640916537446753898873381005535850448e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -2.26548471357135814759065586133601745345092666805731605105989839308832305900191949768e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.56856136042152636864745499626803467747701570337645969278665918810296351408741364840e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -4.48255074360054688238131834296168065172557135920905358164352154448630969015187687499e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 4.56619966800988637898793129440851486107980873809024863561425305126874295268067178801e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -3.81597333294282872581583559942700103331926900424172914177106074836091709159865752408e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.63678053487724707751260697626783885891593791493016491379265204946777211045670615960e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -1.51398164257933964710898171665986511410737733219980979417140085562924634596875563017e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 7.24278345602386851676210506047826420822246500559376040889647916551285989221630819711e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -2.88891626830459350723218099328412217578914954601038686119863249895652809029737934745e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 9.59719898181036663575857261276179540194083274881058286618169370083758218641306764946e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -2.64811367543293387988966817387441229757530457146808054159891759802567729960811992548e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 6.04201418909362106976467138015064536194810537117201428954061434907295912679183849448e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -1.13288541649508118041751198270788445621639048290878149127604057823054487014510567347e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.73151244996618239257199112314250678525910059470480205369884034575880974697338791461e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -2.13522814977566175652818016173551223075398445721839956765100980594656777696996995600e-01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.09751773607848160413869110673825438505378131216432708718954295924780177394997267064e-02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -1.61580494932170317026139049544442892885812277792439584113117496484172419053879898708e-03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 9.57433012294978946531397728731840486773642836205104228434646630602626154207102575497e-05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -4.26115172606869205202745132493304748075964471479903642930011237303391162925986198072e-06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.38298958800694421458738651547755286166537642575090914169204625632511624488640442440e-07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -3.15434025288605144031976010596974001946974995609543721535748916319261879201397044643e-09)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 4.82356872364336815146383574702913568837734092081047520230601339834144374864204220536e-11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -4.65347968332361614985780283973809979932690029695650403412722596287871272868944164634e-13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.61330972151984338818972320382872350752985962075827056997941920528654516802241093365e-15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -7.65712722253446172294321996643259661334528734360491402384245881720504947974618941889e-18)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.00315206806375905680927042642419402837617729582878141293654269070861386455343121457e-20)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -4.67823488694203852929295147942658910943366513902587599688834805295280061153989766567e-24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 5.42784331030702330814913209805860341549196535898588904124741295988710093967131088558e-28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -8.48033607088050589024790469649076336393214555653483679072498587123824764496639393119e-33)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 5.38678975538457226036965671734240034395107611196492658679331149986658879027568426753e-39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -3.16374538409167657752796610509153125477921149181502343813699059314745306802450755203e-44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.81171114010755337144545373726087472870924044681995068325590922531565077520176259988e-44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -2.12518224599976943855815669111195755470966740275125423482269033756614972278324281875e-44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.34263635935093852590059444867684742593087836231966301216975070578889017560759389549e-44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -6.99309631968130547786945826997659785416033441104613988483204974783621090009511212354e-45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.97679666641473578922997037967978768575315112030381704618978104186395317308038799663e-45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -1.02914662367729885237175382124322264439002075945431846631322577735558916377073070681e-45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.86340999808161554465998036301386594999661959859518584115844390884231065866412899967e-46)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -6.29984672974930250076096802152581521034785267762668779142172198560320648227598177519e-47)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.06114476593975974108382448813738674408492134446936551295509200129676957425762855493e-47)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -1.29100594893020385764408454293732511414412187214201378654051353911377525656418964207e-48)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.01295708418471529474900073238291374279037984260859165547005675299775146592711994348e-49)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -3.85645797686287223531258890899878578933576632756354490084215435591125736026369211048e-51))
+      };
+      T result = 0;
+      for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k)
+      {
+         result += (-d[k - 1] * dz) / (k * dz + k * k);
+      }
+      return result;
+   }
+
+   template<class T>
+   static T lanczos_sum_near_2(const T& dz)
+   {
+      static const T d[48] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.96888487550957841138585220622994611985377489508130630837700057227501332853802783571e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -2.54685487861380185221232939396911532213815096219473151461939579496835151047360732452e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.55552167748949946948357664110976074745481263569802725437644778906661083814390424521e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -5.96594384244972046908436642965430637119152525028640569187886872989713864303356592740e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.61206392071125071279258677015155474032235397552388756144191669459747349464120963595e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -3.26386207619544812116284495283640666091191851380376198408981809802540783149068179434e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 5.14119209063000811010153319909166529923295169312754965782286511885151365058895055453e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -6.45796781987366173516756643389460485986669456101668857494954730722833100110613651939e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 6.57848002216691432249235663216198359909768823927158528746723212875688277777327166892e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -5.49763614406879724077940366200859712110749040051198851331880172109188055935892153627e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.79878440118422879619706786668472072947762184485364412917440713970863702012601831523e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -2.18117881690802831493078756446312359535362496025568649851035022806893921424585651770e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.04346085879989815616410913816129789693536068884338152664460700712557690664496356491e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -4.16203393160809415901576300558568214071599197484753461939177893151363492512491744816e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.38265924315387281787206504282410481919445750548305464376847792250029309946303762942e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -3.81511194797468462062874900113250266465621301462447801385359808929965375229616323251e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 8.70467183357417683453667167003713608362889484387619452881332522389524770233094455619e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -1.63213714284756057716179081387804854162483375452448157161319547511874432644723929936e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 2.49457336262308128548970424731422625668341066112088155314174120975542287189333019758e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -3.07620269531262256257667392994057559249714693275375776469485257399496930680150472549e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.02187366435225062095438319574039637826727962739349882824178780109324022923104253736e-01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -2.32787467733840531952793152972131223922164668925536951733638661285196165517774652382e-02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.37936454861394636073464067115999570083944553260438583828963060925061101644510914088e-03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -6.13900038094091115267314860504732881894801020942472019504308090210210731167345398552e-05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.99245982152457111301991970385956762536902876746714853773765158096202639164545608854e-06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -4.54442771789078363056076138819579948120113702520046296917694187019851573438477912893e-08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 6.94926914964866053119681538255564252500374927699409988373657464226793796472537754598e-10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -6.70422350226445404683228568613754929042955139666562491583132456753472072839819516057e-12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 3.76497022572067913016091674317545685518824311681605875941103548614928596445142654530e-14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -1.10315496743460248468022132288915711635897058766184880707096827157196752704473690191e-16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.44523155331686111418148572564943890979552960547133940740999458361025242160963413278e-19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -6.73988808644577660977639361852731370450420349068670037458430193432726909116710442573e-23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 7.81984174508721338476616177429473006273759399181666460057479840823572355207273441830e-27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -1.22175387586288279410299617080503779059482571464350109824108120007426231737351306256e-31)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 7.76069628266069128881232691561697202264350068700303406802593331217743381427492776348e-38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -4.55797760012119196385166534789617212222293557097685410066659856245708610260816713241e-43)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 4.05080524465178727911313037718933906722430509738224888801936471543177490693203242080e-43)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -3.06172965819221083679631791380848228306721487317680820361950045678791125133333041491e-43)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.93432331242636842233461846275246262853067820473357196595254072710231999304513059821e-43)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -1.00748867278864769255014599872258605211683566333279390476878762044733272684660155341e-43)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 4.28864237743622222407442194745385245322813091389014701339281732300960497092852607932e-44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -1.48268166001867959355256619834250603827306390609511540411093653502476081933431007754e-44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 4.12528729298048868682661828587192615782099352227112063181739468363374124346195882740e-45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -9.07612869947754202550701651568771230782100517153410159160000452433811651633069544830e-46)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.52878107636588388950021856856509972417665723455977954669464087724444519346925778688e-46)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -1.85993987583058920731606562273777225552135287406894580374509213860879421694626894310e-47)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, 1.45935754590553989061937536984206183886886144778541444482827659230313539351404405283e-48)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 267, -5.55596198187619704372842019685051223079581761704170979479661609332351755409245768399e-50)),
+      };
+      T result = 0;
+      T z = dz + 2;
+      for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k)
+      {
+         result += (-d[k - 1] * dz) / (z + k * z + k * k - 1);
+      }
+      return result;
+   }
+
+   static double g() { return 3.71521093750000019895196601282805204391479492187500000000000000000000000000000000000e+01; }
+};
+//
+// Lanczos Coefficients for N=58 G=4.7377167968750001136868377216160297393798828125000000000000000000000000000000000000000000000000000000000e+01
+// Max experimental error (with 100-digit precision arithmetic) 89eps
+// Generated with compiler: Microsoft Visual C++ version 14.2 on Win32 at Oct 14 2019
+// Type precision was 334 bits or 103 max_digits10
+//
+struct lanczos58MP : public boost::integral_constant<int, 334>
+{
+   template <class T>
+   static T lanczos_sum(const T& z)
+   {
+      static const T num[58] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.1113345018281139401900617648632565892997531886271137869532357720305909403460902551816191757935253298297e+96)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.3306998523015859302296206498309765162943025964850544682652937543993544826195909937055933931442768067675e+96)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.8268352474100341852641008414682924186512501342670048541149232501353823124314085480609221821688640650080e+95)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.0141386651493209831831274089811845202892902987250465018037980182315440505121630111661568734223655786214e+95)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 8.5471258592914542867143021588167696855338160407933457150021303941501653183920330822783098409082225352649e+94)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.9029900619671536896112969373037726527696919271039767737722503312395772965346303367519600397313792277727e+94)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.4640693221647807642599419508017238730661097576373283904791677661939143319337033201070793440010339999715e+93)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.3008318491825889746629471128738097186407559167000216981000503166575445677111681454415332001004453692360e+92)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.9581961997681479620796339921050983411541681934353890086635121221338490738854914613804353855734829750740e+91)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.9562812093757389383361734216065083810639336069848105427428961256383580773444097085298844542948261561976e+90)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 8.0204448099875032766488461246324914875195022845573308192494619777200657405252573402181380342443147295173e+89)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.1967742477741068422882850261828584111953166907106815923693978537447964053382494347755201222673169434806e+88)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.7934308426826323386245296144249798411531042807557571947289014719343462128587532573403065724298496762577e+87)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.2112731316363645590406244691358512085700135781552933145962419229534561671703452680159817420544888863655e+86)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.7792875367286636291574914918267428357586601357931867786906344130539973047706286380462771311772443260655e+85)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.6729889167781214645382609228554520670924462597343847547527634847733870633193570419233293354907537898968e+84)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.2212896890317209445182351532165347688163702283356828888187120214401748895306876396481747000574259149233e+82)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.6696330100177872775181285832060367195698947756070274789550514016487770556676430692662838020948055174819e+81)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.1787790436987713717592679695802576546659292017904142826938775295267502136179724011234775858106585474335e+80)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.3897471960941486230091766140467565375262975446763006777927562006563131703283610364746875620601313483057e+78)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.7456216276193058883301725852613487104982510349671722342387971953607146505494372335184541893296983766398e+77)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.3855091017101453942895165907767739025127711826384743418432444735139729009897407793448891996393706658957e+76)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.7596919543541505311176214833582242571197674817260097288825507658966682365463135538963387631678553863542e+74)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.5205308568827525377048378465545277453459194177597465928758908233213456983481011601239823019085100837607e+73)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.5219482007379940303673464060102227421305538751659464891709211634879751289944728765835405235116911964067e+71)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.2529929196659743450833612479027982672526994601606551595908472901860777472333846227605233498599036089780e+70)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.2371343799933848311703711400651007221131224388690941908721236718964833912418768528725638940635396117593e+68)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.8015422120873735048084230762717970714811562909437854684093754471976926045882197320273930142628411250042e+66)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.7544934847649309554128203553793825206530899558440305080175611169946112759760674627144360103537889679591e+65)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.6825279122107455550724823529764700516671135432239079326787536307050166777000218851702259835300111357922e+63)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.2137862491643897667607321980849893924427698956617156800113142641018717095876369593791167006646811605785e+61)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.3186571319674830310069793304531422675865920550412368667057521060523822178148626902742473745717612071248e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.2485774541577495056605563690047646700517885331946681444187667959802672435192052254156475697343336771638e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.5749708448011926909660539105173117507305781970952738170400845272354829441805660173686553510885012106315e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.2957728089076810011933348982855845071484336995217889625353037764527196874992238794680831083872659220534e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.3029702073166140154775964636478493296495204191370975362621002042260278819606865308080233433968063616502e+52)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.3651754658248543289835755041517884667332033286508690963566578707866450840862377843752246373050313956333e+50)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.1153610110919853077136756888034644015689784357746290647672760493336488593590043112457135368750990637667e+49)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.2317697361001624160827173449861094521356739436250957059660912760537330301205792128544135654641326400704e+47)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.2591336713897064687825047779362333153357928528455245343833435858589598201567338554890557167949204480368e+45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.1888395650074118534283640535831622534704266864697448915278695723452804398372734472806777342045155424277e+43)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.0342195380047963732482565081644533382537722066923561121178973781344452277931733870503748282543943428982e+41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 8.2659603644818244197377849119572544438113712679642935412688508428331533577481416745415954979034017913781e+38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.0493876469565505074955014266411916314577665137838261525037575218110760155069631757821913430706010515995e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.0380102035661800729809170954585443393379101722448652003355183633039922242269533846456702077836461601594e+34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.4471701800736812643301636372332435764064729819100848382778186520311589961354650397132342954205946278402e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.3391793076015860668513073429148720023215553662036803736563341850799950224212365984411047979319730267348e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.5746079755559823667940853958792940224952894096446926758424644873786146686411034227207764327098030858365e+27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.8730952802737845263408235958198085714879899902329571556827316641606659145317043632556281422581317630775e+25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.1068860106460271425431255001071933519142520498723285368106201466148952145283909421951418316204387374823e+23)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.7146191714834483705600971071352976348572227109511068140706241351872914486137201205172098597005503434574e+20)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.0693465808661148698636384310734985694414606785941298207428612238748657882890467389962396214120403612061e+18)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.5877812671795420049920049903121324610843253367633375770943367999226546473657225178995404939996916553769e+15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.1199728232559097639450648660234135896472362777482676055586950665599850474720777665093211412423570836354e+12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.9536149625531631518225658997937689548178270704423376010017262234330926444650292977902802706698285898435e+09)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.0978434212942028068922584596812569730178537381770594492536210144311893565241511848298648224631091914130e+06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.8136582389003336880560289199735195790527296500214034301547642961678068653936021531092803113827675512051e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.5066282746310005024157652848110452530069867406099383166299235763422936546078420094024669537723756981791e+00))
+      };
+      static const T denom[58] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.1099858780486345185404564746372494973649797888116845868744704000000000000000000000000000000000000000000e+74)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.2787481989562818154790285585287083447455750564964755439725051904000000000000000000000000000000000000000e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.9814423801545723353305894697802330693700024131737540066597268357120000000000000000000000000000000000000e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.2379872707088650213961476468088967648845485386801302969710798700544000000000000000000000000000000000000e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 8.6028610849707118786878466090726746922395786229117545420266938564608000000000000000000000000000000000000e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.0438085338641386367983933867412545578566598680906745465073101805977600000000000000000000000000000000000e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.3492380371843850750819852073737242436575952022390816483000346566721536000000000000000000000000000000000e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.5102990983560640009327873678307954320470630605324516076646299828695859200000000000000000000000000000000e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.6706536806860658574451791386582141941677796433514743219241257405513728000000000000000000000000000000000e+74)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.8043159910377823217375261881225863717725312218178043012454139087028224000000000000000000000000000000000e+74)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.9335160303959039103395501372789994167981664930485977399292586960638443520000000000000000000000000000000e+73)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.1723691196565373582067598608574778201485664959896330847068435199126667264000000000000000000000000000000e+73)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.4438352206893499975371296011596621640882812103203541286914698812249866240000000000000000000000000000000e+72)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.5035118941062978428961903224471555396129604077556196563177106772688896000000000000000000000000000000000e+71)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.3850308579063636618912025850466431356280013115826126911230283854233600000000000000000000000000000000000e+70)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.0836900819838640440767313247219165663768918429617679815795491004563456000000000000000000000000000000000e+70)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.4298706038662999363673291534756645260294395901949985216872998030991360000000000000000000000000000000000e+69)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.7034492632938290783198763770876160868300549275946097010473332643840000000000000000000000000000000000000e+68)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.8389252775111283069889631347879462661235829004870041197088140774400000000000000000000000000000000000000e+67)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.8045026245181087909282578887424942187415211828585867350357833779200000000000000000000000000000000000000e+66)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.6139415015963261948795856116734033680672939822172300204078108032000000000000000000000000000000000000000e+65)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.3187949670862787149323475106066210874520928766305564723661651200000000000000000000000000000000000000000e+64)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.8652947935638867544975258598123447770317269214048194873129760000000000000000000000000000000000000000000e+62)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.7677767608518504817918794029244339508807996285424723220104640000000000000000000000000000000000000000000e+61)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.2641467556495415387682543812562093348191054073538914270730400000000000000000000000000000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.4706517237142185424284275343767027578875512836847707758280000000000000000000000000000000000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.3177422716201009039921461100044177449498643771855331909700000000000000000000000000000000000000000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.4750611894960504179018603471357527802382408288670161342000000000000000000000000000000000000000000000000e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.9330478552107545132079399426533304480054308936780642545000000000000000000000000000000000000000000000000e+55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.2252899213008209896248783169149861832238011945022246000000000000000000000000000000000000000000000000000e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.7217402128877734970019794026056267173695376012268710000000000000000000000000000000000000000000000000000e+52)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.6785124525594845202965146591601984920001061237741320000000000000000000000000000000000000000000000000000e+51)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.5034829951836538559219701088754272365603191632587000000000000000000000000000000000000000000000000000000e+49)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.6637415534451225329152181513653760874075278100800000000000000000000000000000000000000000000000000000000e+48)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.6347190324222080575971451540788329488139570600000000000000000000000000000000000000000000000000000000000e+46)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.1887997793364622891010571019581486512880887480000000000000000000000000000000000000000000000000000000000e+45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.8047716936655096027980248782543659943937913000000000000000000000000000000000000000000000000000000000000e+43)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.0790225058170194637643585929666817947860000000000000000000000000000000000000000000000000000000000000000e+41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.2084757755139694726502828251712490452850000000000000000000000000000000000000000000000000000000000000000e+40)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.1993406165887949960123200495814460898000000000000000000000000000000000000000000000000000000000000000000e+38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.6561413270081694853593737727970949550000000000000000000000000000000000000000000000000000000000000000000e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.5369993949587931998758036774526800000000000000000000000000000000000000000000000000000000000000000000000e+34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.6151991880839964140266135934090000000000000000000000000000000000000000000000000000000000000000000000000e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.4760566491969897737280290058600000000000000000000000000000000000000000000000000000000000000000000000000e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.0621766041618690022809397383500000000000000000000000000000000000000000000000000000000000000000000000000e+29)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.0668475851162648374876202000000000000000000000000000000000000000000000000000000000000000000000000000000e+27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.5410679744103301927030500000000000000000000000000000000000000000000000000000000000000000000000000000000e+24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.5395191798636166637180000000000000000000000000000000000000000000000000000000000000000000000000000000000e+22)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.2147541393617700530500000000000000000000000000000000000000000000000000000000000000000000000000000000000e+20)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.1197409850631024000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+18)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.5899910954161520000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.7660425636804000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.3384219373900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.3043596000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.2435500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.5960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00))
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+   template <class T>
+   static T lanczos_sum_expG_scaled(const T& z)
+   {
+      static const T num[58] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.9525834451195623352844833708766019251484824420589901934439764663785971607902920873854007890984226025387e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.5353913226536305547742063023255223178577430351061832712694094731916543407128432857596013878418835545541e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.0794265040063864629969189140227704423008747481150565046014672784314863153912417986968014303182196879938e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 8.0079363228400099355108372825384509227179448653556047031855632715439781114354847693263728085548142549876e+74)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.2707926617939589278984760255796767920967443801395440059906534121478842405887081438764736244178311493742e+74)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.0558467715603214792617326562510713807234351435955730720590956416562782623810902927804516780978093617536e+73)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.2033080198136382677487341183423922900647133007317553822084317473855699622210307747112227636535549617309e+72)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.4083202075984620999390260696805188384092629914880295342492703293697714617999890327029040466923272486691e+72)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.8486472680848031160157166025706272700120860759432294711200940780548927766558565495831077710008357816723e+71)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.1138175900123376987163744326763008390621758864911227853169463977789770550938948181501331329408292888705e+70)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.1308645173446504769606114641352353002279158988307024846586220931944095152963117782251173128553590002677e+69)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.9120324679281068850671805700697238886511656051607969710283305054986370771314011765262161774820057407221e+68)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.5391934623114467787956807868296099285488891013887607698670475417480968323895750297127042280725645864237e+67)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.1188472337439846560727348944974065682611782369759313015986429928637543111162293072546541343053710871237e+66)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.3839859706266764054133980098731552638450995195061568584278432933554090666516712057667084959928750476621e+64)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.4447818108967399523602631725512074937872788923328188245441957349314890139383300142665492699548078016636e+63)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.4499038978543131336483547267337201487870950383856380855972848092343622627255235050078874464565496828787e+62)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.2406238713440761680092008034709525627435037404776653076097934320335762078719054009676170121443275896208e+61)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.7885604418978046593206212118683810887087891637289025925672325034976573417819599577035132403057170493687e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.4946595358499347633866345682061171079599164941304972231143049023731630101503606670560705515260702923050e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.9513336364509343072555606544850997149882112871146960235297930573184577313990835201997736426755771031690e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.6810080403717774179828377811768440096006474456859136430725963485797286723671499145937476199781240726843e+55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.2645506501577530162354586527854723438171436013868785795302304165655061134281691393986730787208175906833e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.0397326173536285938710693563469993609385607650335155744195392582126325319144559249104863671555936627244e+52)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.2013871048927633852181093624593869925193443374649283179426834256685646298857112848793626713837584764108e+51)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.3289402473981501234144402953028274630427307351359919167469712295902671507115725494100349633541940933204e+49)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 8.6003893195733192859177412982185685700998370832033861854329854490539688708839874262744736474012759445436e+47)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.0727066732760648460132569879963196679351152547539542083857690449447906448979182035004975167951264229374e+46)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.6613224093786683644702502032231164856098499632779487718555251290733786904948988026020403761370171127380e+44)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.7837068244515233545220503730640329863081890096623187288769939552653286719974960799952261791747246686408e+42)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.9165522010589216370481372290739111949387650621903781998282461665273890471374114621564713215060999778073e+41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.5033963322756782307786713227898388231893223357237704976668993902202940789294809098147971301691772648755e+39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.9740002270190565366640741207315377496247453294707036602010614289735470303392852115947439612907179897898e+37)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.4979501813196320177935632677278886186231320810970746337833403723731191512041559167496248429116298871699e+35)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.4069761263574572480694806529063097871169957005541147202721661005052475351188525148368053997631136759790e+34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.9402465143351975112300028774197323450509816779255592414045815705522691518043705429706146342655130265366e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.4881313407932962145111410344090747527354995727266179099775181263231061106933689865989301929428200117871e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.9632810384855297696182113289305607179489664745076688933167066674562917487536504070129264115660678482556e+28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.2725546854039254943463934183457508258081242388204842730157719983831445104894295952204798603845536120509e+26)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.3452549409942328202733488146109233160716224388189413469297783823577482916724384652184656289642575364301e+24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.1584981954307469031764309294640361429335538748027906889408285804565757617154922327898215115914925102238e+22)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.7477051072463293412749200465569024873771231987242784210248733085001441979676968452992807610739566040156e+20)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.1960928676322401992340089643560231337218499440045721085448636142070840811937842162960498037401931828261e+18)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.6071958343894951054088987834710923196788323800906338042869660264064639861175574231931711270452905023878e+16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.0728148958446892912836806181637101367297983133466225777574815613761623459000110314136961372678097371209e+14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.5016195836538037540865015222440859129132562974585463183411281203357391116994585543064375504964287033151e+11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.5579194627421707093560391662678700402228252243270030776955569538161088100804816540797427121002521848777e+09)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.7467358958842104945974935265631802960291549549388120971605962335321138414180962067591937089645593587253e+07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.6332135345687020156244092536439323519014928693505240553789259043703120308196994214855462894182573058664e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.9407647340128848401194943791119430377408353392667765444895085026094746239619902099149777694224783951328e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.8689665916105177080976558363071196803124010350312199134246436579120098844674440713135687985135098450472e-01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.8410303167649082918635413442316246381709300383012975083202578569099476956148029095902566747899894260699e-03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.8751938471236167190844006303614257144787097468775849169694452270347666880072332030058767126104666814717e-06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.3602697452963248452045411104106027969968697679097453973063118187262717386356657326020477164267694748313e-08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.1131092239698914177951080885440635365109643513308304020521218234027520232780450142616357759194523396831e-11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.4171068051802330111071549877540818528598812224565937952488425520621143590937182779724061728889603469712e-14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.8102465534711886967772860840717324393645550944967932350301450628070653877586909697550907928519183677886e-17)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.6595873110837641575235810188999693348770063449340247652053167124146826554900758076335155425689417108046e-21))
+      };
+      static const T denom[58] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.1099858780486345185404564746372494973649797888116845868744704000000000000000000000000000000000000000000e+74)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.2787481989562818154790285585287083447455750564964755439725051904000000000000000000000000000000000000000e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.9814423801545723353305894697802330693700024131737540066597268357120000000000000000000000000000000000000e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.2379872707088650213961476468088967648845485386801302969710798700544000000000000000000000000000000000000e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 8.6028610849707118786878466090726746922395786229117545420266938564608000000000000000000000000000000000000e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.0438085338641386367983933867412545578566598680906745465073101805977600000000000000000000000000000000000e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.3492380371843850750819852073737242436575952022390816483000346566721536000000000000000000000000000000000e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.5102990983560640009327873678307954320470630605324516076646299828695859200000000000000000000000000000000e+75)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.6706536806860658574451791386582141941677796433514743219241257405513728000000000000000000000000000000000e+74)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.8043159910377823217375261881225863717725312218178043012454139087028224000000000000000000000000000000000e+74)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.9335160303959039103395501372789994167981664930485977399292586960638443520000000000000000000000000000000e+73)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.1723691196565373582067598608574778201485664959896330847068435199126667264000000000000000000000000000000e+73)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.4438352206893499975371296011596621640882812103203541286914698812249866240000000000000000000000000000000e+72)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.5035118941062978428961903224471555396129604077556196563177106772688896000000000000000000000000000000000e+71)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.3850308579063636618912025850466431356280013115826126911230283854233600000000000000000000000000000000000e+70)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.0836900819838640440767313247219165663768918429617679815795491004563456000000000000000000000000000000000e+70)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.4298706038662999363673291534756645260294395901949985216872998030991360000000000000000000000000000000000e+69)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.7034492632938290783198763770876160868300549275946097010473332643840000000000000000000000000000000000000e+68)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.8389252775111283069889631347879462661235829004870041197088140774400000000000000000000000000000000000000e+67)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.8045026245181087909282578887424942187415211828585867350357833779200000000000000000000000000000000000000e+66)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.6139415015963261948795856116734033680672939822172300204078108032000000000000000000000000000000000000000e+65)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.3187949670862787149323475106066210874520928766305564723661651200000000000000000000000000000000000000000e+64)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.8652947935638867544975258598123447770317269214048194873129760000000000000000000000000000000000000000000e+62)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.7677767608518504817918794029244339508807996285424723220104640000000000000000000000000000000000000000000e+61)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.2641467556495415387682543812562093348191054073538914270730400000000000000000000000000000000000000000000e+60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.4706517237142185424284275343767027578875512836847707758280000000000000000000000000000000000000000000000e+59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.3177422716201009039921461100044177449498643771855331909700000000000000000000000000000000000000000000000e+58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.4750611894960504179018603471357527802382408288670161342000000000000000000000000000000000000000000000000e+56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.9330478552107545132079399426533304480054308936780642545000000000000000000000000000000000000000000000000e+55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.2252899213008209896248783169149861832238011945022246000000000000000000000000000000000000000000000000000e+54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.7217402128877734970019794026056267173695376012268710000000000000000000000000000000000000000000000000000e+52)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.6785124525594845202965146591601984920001061237741320000000000000000000000000000000000000000000000000000e+51)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.5034829951836538559219701088754272365603191632587000000000000000000000000000000000000000000000000000000e+49)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.6637415534451225329152181513653760874075278100800000000000000000000000000000000000000000000000000000000e+48)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.6347190324222080575971451540788329488139570600000000000000000000000000000000000000000000000000000000000e+46)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.1887997793364622891010571019581486512880887480000000000000000000000000000000000000000000000000000000000e+45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.8047716936655096027980248782543659943937913000000000000000000000000000000000000000000000000000000000000e+43)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.0790225058170194637643585929666817947860000000000000000000000000000000000000000000000000000000000000000e+41)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.2084757755139694726502828251712490452850000000000000000000000000000000000000000000000000000000000000000e+40)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.1993406165887949960123200495814460898000000000000000000000000000000000000000000000000000000000000000000e+38)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.6561413270081694853593737727970949550000000000000000000000000000000000000000000000000000000000000000000e+36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.5369993949587931998758036774526800000000000000000000000000000000000000000000000000000000000000000000000e+34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.6151991880839964140266135934090000000000000000000000000000000000000000000000000000000000000000000000000e+32)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.4760566491969897737280290058600000000000000000000000000000000000000000000000000000000000000000000000000e+30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.0621766041618690022809397383500000000000000000000000000000000000000000000000000000000000000000000000000e+29)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.0668475851162648374876202000000000000000000000000000000000000000000000000000000000000000000000000000000e+27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.5410679744103301927030500000000000000000000000000000000000000000000000000000000000000000000000000000000e+24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.5395191798636166637180000000000000000000000000000000000000000000000000000000000000000000000000000000000e+22)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.2147541393617700530500000000000000000000000000000000000000000000000000000000000000000000000000000000000e+20)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.1197409850631024000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+18)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.5899910954161520000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.7660425636804000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.3384219373900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.3043596000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.2435500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.5960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00))
+      };
+      return boost::math::tools::evaluate_rational(num, denom, z);
+   }
+
+
+   template<class T>
+   static T lanczos_sum_near_1(const T& dz)
+   {
+      static const T d[57] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.7428115435862376558997260696640294500966442454383057764865555979364261022425976429085092772284462056620e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -2.9098470636910381824837046571049540905024165376037355421260734899535717859205986796003654941175663049821e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.3238837075893790405047962895917439384623673303456004530561387555917370190498457070337183015927777421697e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -1.1818710867341557832686340441113771687173935259473061186027784614571488561024113573068868892276452685792e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.2993023860235266500362186023069966658235478225844203105044378872946562122380318851444839578192967323002e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -1.1912180368478885109223112981184136172284705131966546680563227042436992258659147484337283480302880786198e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.6139396362168514560020167846095021752825297585055554665973631410697906644150591916500251626224775776603e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -4.6634802529570780684302635411632208905442609915247254971321402103134398787017804507333676554065934886041e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.8912442659385178766302183254171219505160153159736231877672680444314286802452078408167890642564966971613e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -8.5495375341789279888846473669676987489917192922529063440714880612919546655027506056499234132070763181503e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 8.9953131705119738082952990229447045802828349018683164227185193391425402046621590400831377644280156201943e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -8.0869264878440576629536295016426099545140305890893332059172420721937348112425650207439043097833689822279e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.2468943229845282686806294869840458047361754209121185638286960316366706592206130567941492816463381946909e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -4.1630054452110204332042164710368677551444071577885528134258060122924060097997330723219233292551334541916e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.3999790605522096466954112874401964638803242076322683502391870253501264993933977365040197484368089793844e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -1.1989159366950562464845132094716096217280130489202748985857413544679377185401912495211215199827572320658e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.1934569461829331860249338515130842345952840084924773082558044904616988546739452572774668343010410556738e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -1.9504509773595632752455387440694137287105978110568834596383152715430739170438241704706104769027458757024e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.3443645806133388465801728173699557032879027729815842645734341879259895367471331502957361274245333765268e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -1.7841389657268783911632604958857419096159175608100099391870386517930613345705029477317961997797817456392e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.3263071690820256271926147120746615152585668319664536987434389730938667811945831461118672855948398156120e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -9.0147093132626919930705734140711481562906727339902047165060887486522943229634999363817715017657681660287e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.6071102334369619355078667017356321869894503980205853863658685021270881486705453945159213607404060788769e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -2.4383630842681764529222336922814378927628353308340684972787496418846394508904604721467821529575751627808e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.1286133930578257063116405165630725640730704580877093703762851704304775232899279568326548372516108061737e-01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -3.3692644530387989631839105618463769604011314569959807313957135524319268073994325844277072212634894718838e-02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.0185001434002208420172349105229077528666279911019323889220715333407026262532945659702898548882557288755e-03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -2.2263062380436433070464690537097677591705999260831413712451347815254366329816629201276858957857633159301e-04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.3353139137616007516399230327860238131259262384241927446052286747295202825849286263834250215682608257253e-05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -6.4195296490132509971486202730620553572364290374630355485943647261186824263045109480840776574102283117802e-07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.4317122347228636250935502644177076353230092364254437169086888072416523402594888598203831115818706298660e-08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -7.1116401895712757982110113602984617019673481361481571387831251493876840058692034827601429496435585930404e-10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.5670513725610592064219547014678059161831695745208975662601768645833855387548399162792665797683105415471e-11)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -2.5260646573782426214538742421235036428884108667170155792319000553615370065204316405736286181192562052741e-13)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.8733941140402994491303889414468143535352703737984260742434438594748723811519620261843045417069155536008e-15)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -2.2056577386533803436177435861654503857156683256162837031477537088773467287029340043192251326622052870465e-17)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.0800931908111468667692114269177968638854301916581458483888602672737990097921789711610932672475861001994e-19)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -3.1394496063229749361320583264730160299755358905685423988290847461006304721866926670065937080941317261860e-22)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.9274792450690899704710418936228583371317511924974285800543619049655797337986789330520046119470213637029e-25)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -3.6755223694460581147198804301148887855673388834174147952660909117310772380696272509534022412162907695615e-28)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.0900225572290190698649005514102451202434886376168031607266730359956445823401555519988657304185446296554e-31)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -9.9024654365441546862123770751558932020185466144030552444525982172062830502919077739315180881006251414076e-36)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.8401409342622593684683418781548298452423138616374012775158698166549875044639516398318322746270349752685e-40)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -3.5509630598854356990909041057867643490325454268799807828321700754551551638916414252086883229952366535870e-46)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.9657368621557895021941755410664403576678059155205990324521617023894341207730153756506985102036313160050e-53)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 8.1241524357510805548447946933511907560696760445486904751298400852883111381333879290886698299626153350908e-56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -4.7964162808880362344077245029516705444495147547810713281233063336303852616170950226238109362470235010501e-56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.4347533225708328774658804669618167169988215409141087123873615495103598105335608364600471221104934664685e-56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -1.0479456512751620605515259329413452300868549663188231386090986433707412031359388913176316853836715844262e-56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.7702413521297716432095744498633554542922110264197418721766960511801656053258128107225421844535437414965e-57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -1.1172472608352701420007786830697096251191397605488453881854169564652213625087310098345004527869954910248e-57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.6812745632569367999094411216914045337299158629329933113885292569194336792226670477775358040058394820261e-58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -5.0940899331938988550733986571553993560122282178667089274000678435292023664866549561623149093538369388095e-59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.3990413208296530427672464741601390159299766279095164840741566288983363882627013060272921361169788365065e-60)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -7.7457129143553309783200493485805274806723421714099516756842649457968744562118823820376006640033350414786e-61)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.2197041624023821332095587670691140585500743194040476924703015039327636848179534186153838408314119752602e-62)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -1.7047723462914761686649775942852334082321432815609988664912617018852671864913042227323649381537503179251e-63))
+      };
+      T result = 0;
+      for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k)
+      {
+         result += (-d[k - 1] * dz) / (k * dz + k * k);
+      }
+      return result;
+   }
+
+   template<class T>
+   static T lanczos_sum_near_2(const T& dz)
+   {
+      static const T d[57] = {
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.1662905928411697905258405605703584854097058546117590807018322943510409180314506715189727704455120038255e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -5.2865276330524469503633315971419666291446796012439883450060362841602955272110829770969508625348151344110e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.2219660233923727011658095806761811032946810239961697070082822527681712138952842835075740681056558805545e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -2.1471898769829091933140257345448028662421485176900416920959625594396387278224755880120811584841740984425e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.8108506629663017023576288202278104175560258464862168051112507988271579950339846330515110250714726935097e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -2.1641711509053717182383657533380473756042975817599106212749608660372803916254884680397716414106410031258e+06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.7489314096332467747675642425312337606864580547949737826112168114861342185432170188369658631861013639815e+06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -8.4724786849037234839356479194796060821229710729537665905710787287944594232273268923957076043820505152123e+06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.2519817172723530341690766298268651248835138906207131843033724432774951682486028564360090931772389689559e+07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -1.5532557359535150161664447223551521375257233550726531311510295929236015954526292484349276082718903034254e+07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.6342429895113330905046033016646335037353665731613082814708242545769972330151611687916571207590466290675e+07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -1.4692098728454232462170975109580416322729103219472916098312631671127459727620998375190829900768135597920e+07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.1349180467693002337442162064332669746019375174297711955789632954762786417078957693464106665366428215075e+07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -7.5632302457640823075347957970491681679223652407676639065204661139779189254891918422939089928834865040327e+06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.3602139028787279699176338906645576475531513654199858202869033753097108161316098377414795783646795195944e+06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -2.1781564770643699404196555460989570673904909639666069579972319801392840126860473187109481731392038690946e+06)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.4353253130211266653540571778153094858600293629830279655688388322741879148986220244682882658942335696445e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -3.5435240282512309592551076592408102377879926851607713336111442642626445924365822019934119240733876795141e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.1526261667865026060062626782458367235346781022115660163078870751778821943822555542992468135865376114967e+05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -3.2413730814968410697200758155304075536237935327710818457186113369696959175294570307981528264101370866348e+04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 7.8599121870734324248863589686279377309239133065805881581800599402339736200679855503773749459170204132791e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -1.6377668257261558531404127005983837331367557885561101077531977908963614729639690754651655156526373276599e+03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.9197523005380738606902261922935494412976764483416941348495962454277708460181544072006267228271644673220e+02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -4.4299489087401028354837196175165054006400597113077360830473379437347868849689360216846724154620950362855e+01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.6839760968600182694175565648725095464923929298411152920412000388870216851203160830044900161240884736073e+00)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -6.1211841186792218837353890586540028399627732652134291573554656108241153104326807995702108419307165078338e-01)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.4839254672775355063516929562453773790762108550565402409275434242243168512055903461692839292134763272349e-02)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -4.0446900436498039824930882038167913752019117688189621941029942455212255095042589886820040572146790228293e-03)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.4259604540679199219674266589960434988970631237379997092121152488502215342212782655207033499356597207732e-04)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -1.1662819432736824144566608258931608012907080530838741239388324423687927670373421600053389501450361346193e-05)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.4178658338791266451928074758746505934456557516996342163398372684287698861436808924171077524254379083060e-07)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -1.2920226237184384323812413019935857990607979507557513737013812388314162555859654820969350110668735340875e-08)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 2.8469744980165771885329432448423013838689752067078815649758371478630140330027362965330275099502650356588e-10)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -4.5892826398814320794517525606378651211265264604594412375068674574147845337527175224917342725746156587979e-12)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 5.2203009477948187935105053137418678388241808213010074775815651125432941229706488789085110080538814893051e-14)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -4.0071764354709508994124453699849221531650525550222671429443364906737525324879927767883427021892836113984e-16)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.9622826817063220108064709012206725989960307918188611950534485874633362779114658729325037773191270734438e-18)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -5.7036630218461017970632409261270377964650553992557669797810281540623485979537248227679839983488911988094e-21)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 8.9521045677595146905259180949264876791866636312953998390445326640202924376790113203607493358448772833037e-24)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -6.6775848168912941217401852995810450906306734023598389296925437100201008270660133423441040356945585338087e-27)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.9803220730550206978978787593484142931342246644534949059896766020244771367805337770466949634458076040872e-30)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -1.7990518408632014329157379404081596938445109431006332980973114098434711412087164821902160534448534060827e-34)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.3431158699278209062613044372715762567352361096055698830148755308547762997581572887297656338501121085689e-39)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -6.4512889953126515222750706142725047033542840408835574821053782432341231211557553861105639807627133237603e-45)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 3.5712949902991134825521996829159928713052863755852691744249239606303690103524531369836280748984998481830e-52)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.4759729775024569614177814940895080213705811461280570147704308137991423094447188671055911764625031287276e-54)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -8.7139930908855290554513295892599839263800779861752158476251019536427498588557825717368115652274945883813e-55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.4233907960475632932218656634142149345608818585031048657672084471779614927408553135306513446078671755098e-55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -1.9038779434600254520302015223066920881918842711110146920259738288262023701119647715089263879918197432213e-55)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 6.8496675787588211884718935004472008052724911912938728434253127344504858415646126692300012586778132949530e-56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -2.0297831425771921486916100519977404266947748691416922167961096320991761190057145636867796238254884443749e-56)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 4.8712635957157169685941764659378666193084431023269775678410920776942423498574161990151090862987707496709e-57)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -9.2547981414954593575052648297803007916203550348517241024188916829704035005537638171060497453987203484125e-58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 1.3442368462845102652888331895188311507347132911248615838604886657492687976498041391593065929847726694329e-58)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -1.4072191583666827552083642053400837423373421659342004966749178938352282349787956685790064733145823615594e-59)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, 9.4830105111768027064991929773116440103527225991506525293838437779387018237471847818347678097555938325901e-61)),
+         static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 334, -3.0971820578438671326698299395846141298596444280876893045395714232857615676238866889122426000206260012404e-62)),
+      };
+      T result = 0;
+      T z = dz + 2;
+      for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k)
+      {
+         result += (-d[k - 1] * dz) / (z + k * z + k * k - 1);
+      }
+      return result;
+   }
+
+   static double g() { return 4.7377167968750001136868377216160297393798828125000000000000000000000000000000000000000000000000000000000e+01; }
+};
+
+
+//
+// placeholder for no lanczos info available:
+//
+struct undefined_lanczos : public boost::integral_constant<int, INT_MAX - 1> { };
+
+#if 0
+#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+#define BOOST_MATH_FLT_DIGITS ::std::numeric_limits<float>::digits
+#define BOOST_MATH_DBL_DIGITS ::std::numeric_limits<double>::digits
+#define BOOST_MATH_LDBL_DIGITS ::std::numeric_limits<long double>::digits
+#else
+#define BOOST_MATH_FLT_DIGITS FLT_MANT_DIG
+#define BOOST_MATH_DBL_DIGITS DBL_MANT_DIG
+#define BOOST_MATH_LDBL_DIGITS LDBL_MANT_DIG
+#endif
+#endif
+
+typedef mpl::list<
+   lanczos6m24, 
+/*   lanczos6, */
+   lanczos13m53, 
+/*   lanczos13, */
+   lanczos17m64, 
+   lanczos24m113, 
+   lanczos22,
+   lanczos32MP, 
+   lanczos35MP,
+   lanczos48MP,
+   lanczos49MP,
+   lanczos49MP_2,
+   lanczos58MP,
+   undefined_lanczos> lanczos_list;
+
+template <class Real, class Policy>
+struct lanczos
+{
+   typedef typename mpl::if_<
+      typename mpl::less_equal<
+         typename policies::precision<Real, Policy>::type,
+         boost::integral_constant<int, 0>
+      >::type,
+      boost::integral_constant<int, INT_MAX - 2>,
+      typename policies::precision<Real, Policy>::type
+   >::type target_precision;
+
+   typedef typename mpl::deref<typename mpl::find_if<
+      lanczos_list, 
+      mpl::less_equal<target_precision, mpl::_1> >::type>::type type;
+};
+
+} // namespace lanczos
+} // namespace math
+} // namespace boost
+
+#if !defined(_CRAYC) && !defined(__CUDACC__) && (!defined(__GNUC__) || (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ > 3)))
+#if ((defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64)) && !defined(_MANAGED)
+#include <boost/math/special_functions/detail/lanczos_sse2.hpp>
+#endif
+#endif
+
+#endif // BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS
+
+
+
+
diff --git a/ThirdParty/boost/math/special_functions/legendre.hpp b/ThirdParty/boost/math/special_functions/legendre.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..dd66d8a4722b23a57aa6df2b2fa728569be81907
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/legendre.hpp
@@ -0,0 +1,374 @@
+
+//  (C) Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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_SPECIAL_LEGENDRE_HPP
+#define BOOST_MATH_SPECIAL_LEGENDRE_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <utility>
+#include <vector>
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/special_functions/factorials.hpp>
+#include <boost/math/tools/roots.hpp>
+#include <boost/math/tools/config.hpp>
+#include <boost/math/tools/cxx03_warn.hpp>
+
+namespace boost{
+namespace math{
+
+// Recurrence relation for legendre P and Q polynomials:
+template <class T1, class T2, class T3>
+inline typename tools::promote_args<T1, T2, T3>::type
+   legendre_next(unsigned l, T1 x, T2 Pl, T3 Plm1)
+{
+   typedef typename tools::promote_args<T1, T2, T3>::type result_type;
+   return ((2 * l + 1) * result_type(x) * result_type(Pl) - l * result_type(Plm1)) / (l + 1);
+}
+
+namespace detail{
+
+// Implement Legendre P and Q polynomials via recurrence:
+template <class T, class Policy>
+T legendre_imp(unsigned l, T x, const Policy& pol, bool second = false)
+{
+   static const char* function = "boost::math::legrendre_p<%1%>(unsigned, %1%)";
+   // Error handling:
+   if((x < -1) || (x > 1))
+      return policies::raise_domain_error<T>(
+         function,
+         "The Legendre Polynomial is defined for"
+         " -1 <= x <= 1, but got x = %1%.", x, pol);
+
+   T p0, p1;
+   if(second)
+   {
+      // A solution of the second kind (Q):
+      p0 = (boost::math::log1p(x, pol) - boost::math::log1p(-x, pol)) / 2;
+      p1 = x * p0 - 1;
+   }
+   else
+   {
+      // A solution of the first kind (P):
+      p0 = 1;
+      p1 = x;
+   }
+   if(l == 0)
+      return p0;
+
+   unsigned n = 1;
+
+   while(n < l)
+   {
+      std::swap(p0, p1);
+      p1 = boost::math::legendre_next(n, x, p0, p1);
+      ++n;
+   }
+   return p1;
+}
+
+template <class T, class Policy>
+T legendre_p_prime_imp(unsigned l, T x, const Policy& pol, T* Pn 
+#ifdef BOOST_NO_CXX11_NULLPTR
+   = 0
+#else
+   = nullptr
+#endif
+)
+{
+   static const char* function = "boost::math::legrendre_p_prime<%1%>(unsigned, %1%)";
+   // Error handling:
+   if ((x < -1) || (x > 1))
+      return policies::raise_domain_error<T>(
+         function,
+         "The Legendre Polynomial is defined for"
+         " -1 <= x <= 1, but got x = %1%.", x, pol);
+   
+   if (l == 0)
+    {
+        if (Pn)
+        {
+           *Pn = 1;
+        }
+        return 0;
+    }
+    T p0 = 1;
+    T p1 = x;
+    T p_prime;
+    bool odd = l & 1;
+    // If the order is odd, we sum all the even polynomials:
+    if (odd)
+    {
+        p_prime = p0;
+    }
+    else // Otherwise we sum the odd polynomials * (2n+1)
+    {
+        p_prime = 3*p1;
+    }
+
+    unsigned n = 1;
+    while(n < l - 1)
+    {
+       std::swap(p0, p1);
+       p1 = boost::math::legendre_next(n, x, p0, p1);
+       ++n;
+       if (odd)
+       {
+          p_prime += (2*n+1)*p1;
+          odd = false;
+       }
+       else
+       {
+           odd = true;
+       }
+    }
+    // This allows us to evaluate the derivative and the function for the same cost.
+    if (Pn)
+    {
+        std::swap(p0, p1);
+        *Pn = boost::math::legendre_next(n, x, p0, p1);
+    }
+    return p_prime;
+}
+
+template <class T, class Policy>
+struct legendre_p_zero_func
+{
+   int n;
+   const Policy& pol;
+
+   legendre_p_zero_func(int n_, const Policy& p) : n(n_), pol(p) {}
+
+   std::pair<T, T> operator()(T x) const
+   { 
+      T Pn;
+      T Pn_prime = detail::legendre_p_prime_imp(n, x, pol, &Pn);
+      return std::pair<T, T>(Pn, Pn_prime); 
+   };
+};
+
+template <class T, class Policy>
+std::vector<T> legendre_p_zeros_imp(int n, const Policy& pol)
+{
+    using std::cos;
+    using std::sin;
+    using std::ceil;
+    using std::sqrt;
+    using boost::math::constants::pi;
+    using boost::math::constants::half;
+    using boost::math::tools::newton_raphson_iterate;
+
+    BOOST_ASSERT(n >= 0);
+    std::vector<T> zeros;
+    if (n == 0)
+    {
+        // There are no zeros of P_0(x) = 1.
+        return zeros;
+    }
+    int k;
+    if (n & 1)
+    {
+        zeros.resize((n-1)/2 + 1, std::numeric_limits<T>::quiet_NaN());
+        zeros[0] = 0;
+        k = 1;
+    }
+    else
+    {
+        zeros.resize(n/2, std::numeric_limits<T>::quiet_NaN());
+        k = 0;
+    }
+    T half_n = ceil(n*half<T>());
+
+    while (k < (int)zeros.size())
+    {
+        // Bracket the root: Szego:
+        // Gabriel Szego, Inequalities for the Zeros of Legendre Polynomials and Related Functions, Transactions of the American Mathematical Society, Vol. 39, No. 1 (1936)
+        T theta_nk =  ((half_n - half<T>()*half<T>() - static_cast<T>(k))*pi<T>())/(static_cast<T>(n)+half<T>());
+        T lower_bound = cos( (half_n - static_cast<T>(k))*pi<T>()/static_cast<T>(n + 1));
+        T cos_nk = cos(theta_nk);
+        T upper_bound = cos_nk;
+        // First guess follows from:
+        //  F. G. Tricomi, Sugli zeri dei polinomi sferici ed ultrasferici, Ann. Mat. Pura Appl., 31 (1950), pp. 93-97;
+        T inv_n_sq = 1/static_cast<T>(n*n);
+        T sin_nk = sin(theta_nk);
+        T x_nk_guess = (1 - inv_n_sq/static_cast<T>(8) + inv_n_sq /static_cast<T>(8*n) - (inv_n_sq*inv_n_sq/384)*(39  - 28 / (sin_nk*sin_nk) ) )*cos_nk;
+
+        boost::uintmax_t number_of_iterations = policies::get_max_root_iterations<Policy>();
+
+        legendre_p_zero_func<T, Policy> f(n, pol);
+
+        const T x_nk = newton_raphson_iterate(f, x_nk_guess,
+                                              lower_bound, upper_bound,
+                                              policies::digits<T, Policy>(),
+                                              number_of_iterations);
+
+        BOOST_ASSERT(lower_bound < x_nk);
+        BOOST_ASSERT(upper_bound > x_nk);
+        zeros[k] = x_nk;
+        ++k;
+    }
+    return zeros;
+}
+
+} // namespace detail
+
+template <class T, class Policy>
+inline typename boost::enable_if_c<policies::is_policy<Policy>::value, typename tools::promote_args<T>::type>::type
+   legendre_p(int l, T x, const Policy& pol)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   static const char* function = "boost::math::legendre_p<%1%>(unsigned, %1%)";
+   if(l < 0)
+      return policies::checked_narrowing_cast<result_type, Policy>(detail::legendre_imp(-l-1, static_cast<value_type>(x), pol, false), function);
+   return policies::checked_narrowing_cast<result_type, Policy>(detail::legendre_imp(l, static_cast<value_type>(x), pol, false), function);
+}
+
+
+template <class T, class Policy>
+inline typename boost::enable_if_c<policies::is_policy<Policy>::value, typename tools::promote_args<T>::type>::type
+   legendre_p_prime(int l, T x, const Policy& pol)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   static const char* function = "boost::math::legendre_p_prime<%1%>(unsigned, %1%)";
+   if(l < 0)
+      return policies::checked_narrowing_cast<result_type, Policy>(detail::legendre_p_prime_imp(-l-1, static_cast<value_type>(x), pol), function);
+   return policies::checked_narrowing_cast<result_type, Policy>(detail::legendre_p_prime_imp(l, static_cast<value_type>(x), pol), function);
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type
+   legendre_p(int l, T x)
+{
+   return boost::math::legendre_p(l, x, policies::policy<>());
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type
+   legendre_p_prime(int l, T x)
+{
+   return boost::math::legendre_p_prime(l, x, policies::policy<>());
+}
+
+template <class T, class Policy>
+inline std::vector<T> legendre_p_zeros(int l, const Policy& pol)
+{
+    if(l < 0)
+        return detail::legendre_p_zeros_imp<T>(-l-1, pol);
+
+    return detail::legendre_p_zeros_imp<T>(l, pol);
+}
+
+
+template <class T>
+inline std::vector<T> legendre_p_zeros(int l)
+{
+   return boost::math::legendre_p_zeros<T>(l, policies::policy<>());
+}
+
+template <class T, class Policy>
+inline typename boost::enable_if_c<policies::is_policy<Policy>::value, typename tools::promote_args<T>::type>::type
+   legendre_q(unsigned l, T x, const Policy& pol)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   return policies::checked_narrowing_cast<result_type, Policy>(detail::legendre_imp(l, static_cast<value_type>(x), pol, true), "boost::math::legendre_q<%1%>(unsigned, %1%)");
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type
+   legendre_q(unsigned l, T x)
+{
+   return boost::math::legendre_q(l, x, policies::policy<>());
+}
+
+// Recurrence for associated polynomials:
+template <class T1, class T2, class T3>
+inline typename tools::promote_args<T1, T2, T3>::type
+   legendre_next(unsigned l, unsigned m, T1 x, T2 Pl, T3 Plm1)
+{
+   typedef typename tools::promote_args<T1, T2, T3>::type result_type;
+   return ((2 * l + 1) * result_type(x) * result_type(Pl) - (l + m) * result_type(Plm1)) / (l + 1 - m);
+}
+
+namespace detail{
+// Legendre P associated polynomial:
+template <class T, class Policy>
+T legendre_p_imp(int l, int m, T x, T sin_theta_power, const Policy& pol)
+{
+   // Error handling:
+   if((x < -1) || (x > 1))
+      return policies::raise_domain_error<T>(
+      "boost::math::legendre_p<%1%>(int, int, %1%)",
+         "The associated Legendre Polynomial is defined for"
+         " -1 <= x <= 1, but got x = %1%.", x, pol);
+   // Handle negative arguments first:
+   if(l < 0)
+      return legendre_p_imp(-l-1, m, x, sin_theta_power, pol);
+   if(m < 0)
+   {
+      int sign = (m&1) ? -1 : 1;
+      return sign * boost::math::tgamma_ratio(static_cast<T>(l+m+1), static_cast<T>(l+1-m), pol) * legendre_p_imp(l, -m, x, sin_theta_power, pol);
+   }
+   // Special cases:
+   if(m > l)
+      return 0;
+   if(m == 0)
+      return boost::math::legendre_p(l, x, pol);
+
+   T p0 = boost::math::double_factorial<T>(2 * m - 1, pol) * sin_theta_power;
+
+   if(m&1)
+      p0 *= -1;
+   if(m == l)
+      return p0;
+
+   T p1 = x * (2 * m + 1) * p0;
+
+   int n = m + 1;
+
+   while(n < l)
+   {
+      std::swap(p0, p1);
+      p1 = boost::math::legendre_next(n, m, x, p0, p1);
+      ++n;
+   }
+   return p1;
+}
+
+template <class T, class Policy>
+inline T legendre_p_imp(int l, int m, T x, const Policy& pol)
+{
+   BOOST_MATH_STD_USING
+   // TODO: we really could use that mythical "pow1p" function here:
+   return legendre_p_imp(l, m, x, static_cast<T>(pow(1 - x*x, T(abs(m))/2)), pol);
+}
+
+}
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type
+   legendre_p(int l, int m, T x, const Policy& pol)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   return policies::checked_narrowing_cast<result_type, Policy>(detail::legendre_p_imp(l, m, static_cast<value_type>(x), pol), "boost::math::legendre_p<%1%>(int, int, %1%)");
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type
+   legendre_p(int l, int m, T x)
+{
+   return boost::math::legendre_p(l, m, x, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_SPECIAL_LEGENDRE_HPP
diff --git a/ThirdParty/boost/math/special_functions/legendre_stieltjes.hpp b/ThirdParty/boost/math/special_functions/legendre_stieltjes.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1f30ddc3b739aedef7f51ccdb0b54ad5cea43b63
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/legendre_stieltjes.hpp
@@ -0,0 +1,235 @@
+// Copyright Nick Thompson 2017.
+// Use, modification and distribution are subject to 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_SPECIAL_LEGENDRE_STIELTJES_HPP
+#define BOOST_MATH_SPECIAL_LEGENDRE_STIELTJES_HPP
+
+/*
+ * Constructs the Legendre-Stieltjes polynomial of degree m.
+ * The Legendre-Stieltjes polynomials are used to create extensions for Gaussian quadratures,
+ * commonly called "Gauss-Konrod" quadratures.
+ *
+ * References:
+ * Patterson, TNL. "The optimum addition of points to quadrature formulae." Mathematics of Computation 22.104 (1968): 847-856.
+ */
+
+#include <iostream>
+#include <vector>
+#include <boost/math/tools/roots.hpp>
+#include <boost/math/special_functions/legendre.hpp>
+
+namespace boost{
+namespace math{
+
+template<class Real>
+class legendre_stieltjes
+{
+public:
+    legendre_stieltjes(size_t m)
+    {
+        if (m == 0)
+        {
+           throw std::domain_error("The Legendre-Stieltjes polynomial is defined for order m > 0.\n");
+        }
+        m_m = static_cast<int>(m);
+        std::ptrdiff_t n = m - 1;
+        std::ptrdiff_t q;
+        std::ptrdiff_t r;
+        bool odd = n & 1;
+        if (odd)
+        {
+           q = 1;
+           r = (n-1)/2 + 2;
+        }
+        else
+        {
+           q = 0;
+           r = n/2 + 1;
+        }
+        m_a.resize(r + 1);
+        // We'll keep the ones-based indexing at the cost of storing a superfluous element
+        // so that we can follow Patterson's notation exactly.
+        m_a[r] = static_cast<Real>(1);
+        // Make sure using the zero index is a bug:
+        m_a[0] = std::numeric_limits<Real>::quiet_NaN();
+
+        for (std::ptrdiff_t k = 1; k < r; ++k)
+        {
+            Real ratio = 1;
+            m_a[r - k] = 0;
+            for (std::ptrdiff_t i = r + 1 - k; i <= r; ++i)
+            {
+                // See Patterson, equation 12
+                std::ptrdiff_t num = (n - q + 2*(i + k - 1))*(n + q + 2*(k - i + 1))*(n-1-q+2*(i-k))*(2*(k+i-1) -1 -q -n);
+                std::ptrdiff_t den = (n - q + 2*(i - k))*(2*(k + i - 1) - q - n)*(n + 1 + q + 2*(k - i))*(n - 1 - q + 2*(i + k));
+                ratio *= static_cast<Real>(num)/static_cast<Real>(den);
+                m_a[r - k] -= ratio*m_a[i];
+            }
+        }
+    }
+
+
+    Real norm_sq() const
+    {
+        Real t = 0;
+        bool odd = m_m & 1;
+        for (size_t i = 1; i < m_a.size(); ++i)
+        {
+            if(odd)
+            {
+                t += 2*m_a[i]*m_a[i]/static_cast<Real>(4*i-1);
+            }
+            else
+            {
+                t += 2*m_a[i]*m_a[i]/static_cast<Real>(4*i-3);
+            }
+        }
+        return t;
+    }
+
+
+    Real operator()(Real x) const
+    {
+        // Trivial implementation:
+        // Em += m_a[i]*legendre_p(2*i - 1, x);  m odd
+        // Em += m_a[i]*legendre_p(2*i - 2, x);  m even
+        size_t r = m_a.size() - 1;
+        Real p0 = 1;
+        Real p1 = x;
+
+        Real Em;
+        bool odd = m_m & 1;
+        if (odd)
+        {
+            Em = m_a[1]*p1;
+        }
+        else
+        {
+            Em = m_a[1]*p0;
+        }
+
+        unsigned n = 1;
+        for (size_t i = 2; i <= r; ++i)
+        {
+            std::swap(p0, p1);
+            p1 = boost::math::legendre_next(n, x, p0, p1);
+            ++n;
+            if (!odd)
+            {
+               Em += m_a[i]*p1;
+            }
+            std::swap(p0, p1);
+            p1 = boost::math::legendre_next(n, x, p0, p1);
+            ++n;
+            if(odd)
+            {
+                Em += m_a[i]*p1;
+            }
+        }
+        return Em;
+    }
+
+
+    Real prime(Real x) const
+    {
+        Real Em_prime = 0;
+
+        for (size_t i = 1; i < m_a.size(); ++i)
+        {
+            if(m_m & 1)
+            {
+                Em_prime += m_a[i]*detail::legendre_p_prime_imp(static_cast<unsigned>(2*i - 1), x, policies::policy<>());
+            }
+            else
+            {
+                Em_prime += m_a[i]*detail::legendre_p_prime_imp(static_cast<unsigned>(2*i - 2), x, policies::policy<>());
+            }
+        }
+        return Em_prime;
+    }
+
+    std::vector<Real> zeros() const
+    {
+        using boost::math::constants::half;
+
+        std::vector<Real> stieltjes_zeros;
+        std::vector<Real> legendre_zeros = legendre_p_zeros<Real>(m_m - 1);
+        int k;
+        if (m_m & 1)
+        {
+            stieltjes_zeros.resize(legendre_zeros.size() + 1, std::numeric_limits<Real>::quiet_NaN());
+            stieltjes_zeros[0] = 0;
+            k = 1;
+        }
+        else
+        {
+            stieltjes_zeros.resize(legendre_zeros.size(), std::numeric_limits<Real>::quiet_NaN());
+            k = 0;
+        }
+
+        while (k < (int)stieltjes_zeros.size())
+        {
+            Real lower_bound;
+            Real upper_bound;
+            if (m_m & 1)
+            {
+                lower_bound = legendre_zeros[k - 1];
+                if (k == (int)legendre_zeros.size())
+                {
+                    upper_bound = 1;
+                }
+                else
+                {
+                    upper_bound = legendre_zeros[k];
+                }
+            }
+            else
+            {
+                lower_bound = legendre_zeros[k];
+                if (k == (int)legendre_zeros.size() - 1)
+                {
+                    upper_bound = 1;
+                }
+                else
+                {
+                    upper_bound = legendre_zeros[k+1];
+                }
+            }
+
+            // The root bracketing is not very tight; to keep weird stuff from happening
+            // in the Newton's method, let's tighten up the tolerance using a few bisections.
+            boost::math::tools::eps_tolerance<Real> tol(6);
+            auto g = [&](Real t) { return this->operator()(t); };
+            auto p = boost::math::tools::bisect(g, lower_bound, upper_bound, tol);
+
+            Real x_nk_guess = p.first + (p.second - p.first)*half<Real>();
+            boost::uintmax_t number_of_iterations = 500;
+
+            auto f = [&] (Real x) { Real Pn = this->operator()(x);
+                                    Real Pn_prime = this->prime(x);
+                                    return std::pair<Real, Real>(Pn, Pn_prime); };
+
+            const Real x_nk = boost::math::tools::newton_raphson_iterate(f, x_nk_guess,
+                                                  p.first, p.second,
+                                                  2*std::numeric_limits<Real>::digits10,
+                                                  number_of_iterations);
+
+            BOOST_ASSERT(p.first < x_nk);
+            BOOST_ASSERT(x_nk < p.second);
+            stieltjes_zeros[k] = x_nk;
+            ++k;
+        }
+        return stieltjes_zeros;
+    }
+
+private:
+    // Coefficients of Legendre expansion
+    std::vector<Real> m_a;
+    int m_m;
+};
+
+}}
+#endif
diff --git a/ThirdParty/boost/math/special_functions/log1p.hpp b/ThirdParty/boost/math/special_functions/log1p.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f7cc276b56839af0dd7e693d28530c5648433e38
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/log1p.hpp
@@ -0,0 +1,511 @@
+//  (C) Copyright John Maddock 2005-2006.
+//  Use, modification and distribution are subject to 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_LOG1P_INCLUDED
+#define BOOST_MATH_LOG1P_INCLUDED
+
+#ifdef _MSC_VER
+#pragma once
+#pragma warning(push)
+#pragma warning(disable:4702) // Unreachable code (release mode only warning)
+#endif
+
+#include <boost/config/no_tr1/cmath.hpp>
+#include <math.h> // platform's ::log1p
+#include <boost/limits.hpp>
+#include <boost/math/tools/config.hpp>
+#include <boost/math/tools/series.hpp>
+#include <boost/math/tools/rational.hpp>
+#include <boost/math/tools/big_constant.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/special_functions/math_fwd.hpp>
+
+#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+#  include <boost/static_assert.hpp>
+#else
+#  include <boost/assert.hpp>
+#endif
+
+#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128)
+//
+// This is the only way we can avoid
+// warning: non-standard suffix on floating constant [-Wpedantic]
+// when building with -Wall -pedantic.  Neither __extension__
+// nor #pragma diagnostic ignored work :(
+//
+#pragma GCC system_header
+#endif
+
+namespace boost{ namespace math{
+
+namespace detail
+{
+  // Functor log1p_series returns the next term in the Taylor series
+  //   pow(-1, k-1)*pow(x, k) / k
+  // each time that operator() is invoked.
+  //
+  template <class T>
+  struct log1p_series
+  {
+     typedef T result_type;
+
+     log1p_series(T x)
+        : k(0), m_mult(-x), m_prod(-1){}
+
+     T operator()()
+     {
+        m_prod *= m_mult;
+        return m_prod / ++k;
+     }
+
+     int count()const
+     {
+        return k;
+     }
+
+  private:
+     int k;
+     const T m_mult;
+     T m_prod;
+     log1p_series(const log1p_series&);
+     log1p_series& operator=(const log1p_series&);
+  };
+
+// Algorithm log1p is part of C99, but is not yet provided by many compilers.
+//
+// This version uses a Taylor series expansion for 0.5 > x > epsilon, which may
+// require up to std::numeric_limits<T>::digits+1 terms to be calculated. 
+// It would be much more efficient to use the equivalence:
+//   log(1+x) == (log(1+x) * x) / ((1-x) - 1)
+// Unfortunately many optimizing compilers make such a mess of this, that 
+// it performs no better than log(1+x): which is to say not very well at all.
+//
+template <class T, class Policy>
+T log1p_imp(T const & x, const Policy& pol, const boost::integral_constant<int, 0>&)
+{ // The function returns the natural logarithm of 1 + x.
+   typedef typename tools::promote_args<T>::type result_type;
+   BOOST_MATH_STD_USING
+
+   static const char* function = "boost::math::log1p<%1%>(%1%)";
+
+   if((x < -1) || (boost::math::isnan)(x))
+      return policies::raise_domain_error<T>(
+         function, "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+   if(x == -1)
+      return -policies::raise_overflow_error<T>(
+         function, 0, pol);
+
+   result_type a = abs(result_type(x));
+   if(a > result_type(0.5f))
+      return log(1 + result_type(x));
+   // Note that without numeric_limits specialisation support, 
+   // epsilon just returns zero, and our "optimisation" will always fail:
+   if(a < tools::epsilon<result_type>())
+      return x;
+   detail::log1p_series<result_type> s(x);
+   boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) && !BOOST_WORKAROUND(__EDG_VERSION__, <= 245)
+   result_type result = tools::sum_series(s, policies::get_epsilon<result_type, Policy>(), max_iter);
+#else
+   result_type zero = 0;
+   result_type result = tools::sum_series(s, policies::get_epsilon<result_type, Policy>(), max_iter, zero);
+#endif
+   policies::check_series_iterations<T>(function, max_iter, pol);
+   return result;
+}
+
+template <class T, class Policy>
+T log1p_imp(T const& x, const Policy& pol, const boost::integral_constant<int, 53>&)
+{ // The function returns the natural logarithm of 1 + x.
+   BOOST_MATH_STD_USING
+
+   static const char* function = "boost::math::log1p<%1%>(%1%)";
+
+   if(x < -1)
+      return policies::raise_domain_error<T>(
+         function, "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+   if(x == -1)
+      return -policies::raise_overflow_error<T>(
+         function, 0, pol);
+
+   T a = fabs(x);
+   if(a > 0.5f)
+      return log(1 + x);
+   // Note that without numeric_limits specialisation support, 
+   // epsilon just returns zero, and our "optimisation" will always fail:
+   if(a < tools::epsilon<T>())
+      return x;
+
+   // Maximum Deviation Found:                     1.846e-017
+   // Expected Error Term:                         1.843e-017
+   // Maximum Relative Change in Control Points:   8.138e-004
+   // Max Error found at double precision =        3.250766e-016
+   static const T P[] = {    
+       0.15141069795941984e-16L,
+       0.35495104378055055e-15L,
+       0.33333333333332835L,
+       0.99249063543365859L,
+       1.1143969784156509L,
+       0.58052937949269651L,
+       0.13703234928513215L,
+       0.011294864812099712L
+     };
+   static const T Q[] = {    
+       1L,
+       3.7274719063011499L,
+       5.5387948649720334L,
+       4.159201143419005L,
+       1.6423855110312755L,
+       0.31706251443180914L,
+       0.022665554431410243L,
+       -0.29252538135177773e-5L
+     };
+
+   T result = 1 - x / 2 + tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x);
+   result *= x;
+
+   return result;
+}
+
+template <class T, class Policy>
+T log1p_imp(T const& x, const Policy& pol, const boost::integral_constant<int, 64>&)
+{ // The function returns the natural logarithm of 1 + x.
+   BOOST_MATH_STD_USING
+
+   static const char* function = "boost::math::log1p<%1%>(%1%)";
+
+   if(x < -1)
+      return policies::raise_domain_error<T>(
+         function, "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+   if(x == -1)
+      return -policies::raise_overflow_error<T>(
+         function, 0, pol);
+
+   T a = fabs(x);
+   if(a > 0.5f)
+      return log(1 + x);
+   // Note that without numeric_limits specialisation support, 
+   // epsilon just returns zero, and our "optimisation" will always fail:
+   if(a < tools::epsilon<T>())
+      return x;
+
+   // Maximum Deviation Found:                     8.089e-20
+   // Expected Error Term:                         8.088e-20
+   // Maximum Relative Change in Control Points:   9.648e-05
+   // Max Error found at long double precision =   2.242324e-19
+   static const T P[] = {    
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.807533446680736736712e-19),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.490881544804798926426e-18),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.333333333333333373941),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 1.17141290782087994162),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 1.62790522814926264694),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 1.13156411870766876113),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.408087379932853785336),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.0706537026422828914622),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.00441709903782239229447)
+   };
+   static const T Q[] = {    
+      BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 4.26423872346263928361),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 7.48189472704477708962),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 6.94757016732904280913),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 3.6493508622280767304),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 1.06884863623790638317),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.158292216998514145947),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.00885295524069924328658),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.560026216133415663808e-6)
+   };
+
+   T result = 1 - x / 2 + tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x);
+   result *= x;
+
+   return result;
+}
+
+template <class T, class Policy>
+T log1p_imp(T const& x, const Policy& pol, const boost::integral_constant<int, 24>&)
+{ // The function returns the natural logarithm of 1 + x.
+   BOOST_MATH_STD_USING
+
+   static const char* function = "boost::math::log1p<%1%>(%1%)";
+
+   if(x < -1)
+      return policies::raise_domain_error<T>(
+         function, "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+   if(x == -1)
+      return -policies::raise_overflow_error<T>(
+         function, 0, pol);
+
+   T a = fabs(x);
+   if(a > 0.5f)
+      return log(1 + x);
+   // Note that without numeric_limits specialisation support, 
+   // epsilon just returns zero, and our "optimisation" will always fail:
+   if(a < tools::epsilon<T>())
+      return x;
+
+   // Maximum Deviation Found:                     6.910e-08
+   // Expected Error Term:                         6.910e-08
+   // Maximum Relative Change in Control Points:   2.509e-04
+   // Max Error found at double precision =        6.910422e-08
+   // Max Error found at float precision =         8.357242e-08
+   static const T P[] = {    
+      -0.671192866803148236519e-7L,
+      0.119670999140731844725e-6L,
+      0.333339469182083148598L,
+      0.237827183019664122066L
+   };
+   static const T Q[] = {    
+      1L,
+      1.46348272586988539733L,
+      0.497859871350117338894L,
+      -0.00471666268910169651936L
+   };
+
+   T result = 1 - x / 2 + tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x);
+   result *= x;
+
+   return result;
+}
+
+template <class T, class Policy, class tag>
+struct log1p_initializer
+{
+   struct init
+   {
+      init()
+      {
+         do_init(tag());
+      }
+      template <int N>
+      static void do_init(const boost::integral_constant<int, N>&){}
+      static void do_init(const boost::integral_constant<int, 64>&)
+      {
+         boost::math::log1p(static_cast<T>(0.25), Policy());
+      }
+      void force_instantiate()const{}
+   };
+   static const init initializer;
+   static void force_instantiate()
+   {
+      initializer.force_instantiate();
+   }
+};
+
+template <class T, class Policy, class tag>
+const typename log1p_initializer<T, Policy, tag>::init log1p_initializer<T, Policy, tag>::initializer;
+
+
+} // namespace detail
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type log1p(T x, const Policy&)
+{ 
+   typedef typename tools::promote_args<T>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   typedef typename policies::precision<result_type, Policy>::type precision_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   typedef boost::integral_constant<int,
+      precision_type::value <= 0 ? 0 :
+      precision_type::value <= 53 ? 53 :
+      precision_type::value <= 64 ? 64 : 0
+   > tag_type;
+
+   detail::log1p_initializer<value_type, forwarding_policy, tag_type>::force_instantiate();
+
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+      detail::log1p_imp(static_cast<value_type>(x), forwarding_policy(), tag_type()), "boost::math::log1p<%1%>(%1%)");
+}
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+// These overloads work around a type deduction bug:
+inline float log1p(float z)
+{
+   return log1p<float>(z);
+}
+inline double log1p(double z)
+{
+   return log1p<double>(z);
+}
+#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+inline long double log1p(long double z)
+{
+   return log1p<long double>(z);
+}
+#endif
+#endif
+
+#ifdef log1p
+#  ifndef BOOST_HAS_LOG1P
+#     define BOOST_HAS_LOG1P
+#  endif
+#  undef log1p
+#endif
+
+#if defined(BOOST_HAS_LOG1P) && !(defined(__osf__) && defined(__DECCXX_VER))
+#  ifdef BOOST_MATH_USE_C99
+template <class Policy>
+inline float log1p(float x, const Policy& pol)
+{ 
+   if(x < -1)
+      return policies::raise_domain_error<float>(
+         "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+   if(x == -1)
+      return -policies::raise_overflow_error<float>(
+         "log1p<%1%>(%1%)", 0, pol);
+   return ::log1pf(x); 
+}
+#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+template <class Policy>
+inline long double log1p(long double x, const Policy& pol)
+{ 
+   if(x < -1)
+      return policies::raise_domain_error<long double>(
+         "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+   if(x == -1)
+      return -policies::raise_overflow_error<long double>(
+         "log1p<%1%>(%1%)", 0, pol);
+   return ::log1pl(x); 
+}
+#endif
+#else
+template <class Policy>
+inline float log1p(float x, const Policy& pol)
+{ 
+   if(x < -1)
+      return policies::raise_domain_error<float>(
+         "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+   if(x == -1)
+      return -policies::raise_overflow_error<float>(
+         "log1p<%1%>(%1%)", 0, pol);
+   return ::log1p(x); 
+}
+#endif
+template <class Policy>
+inline double log1p(double x, const Policy& pol)
+{ 
+   if(x < -1)
+      return policies::raise_domain_error<double>(
+         "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+   if(x == -1)
+      return -policies::raise_overflow_error<double>(
+         "log1p<%1%>(%1%)", 0, pol);
+   return ::log1p(x); 
+}
+#elif defined(_MSC_VER) && (BOOST_MSVC >= 1400)
+//
+// You should only enable this branch if you are absolutely sure
+// that your compilers optimizer won't mess this code up!!
+// Currently tested with VC8 and Intel 9.1.
+//
+template <class Policy>
+inline double log1p(double x, const Policy& pol)
+{
+   if(x < -1)
+      return policies::raise_domain_error<double>(
+         "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+   if(x == -1)
+      return -policies::raise_overflow_error<double>(
+         "log1p<%1%>(%1%)", 0, pol);
+   double u = 1+x;
+   if(u == 1.0) 
+      return x; 
+   else
+      return ::log(u)*(x/(u-1.0));
+}
+template <class Policy>
+inline float log1p(float x, const Policy& pol)
+{
+   return static_cast<float>(boost::math::log1p(static_cast<double>(x), pol));
+}
+#ifndef _WIN32_WCE
+//
+// For some reason this fails to compile under WinCE...
+// Needs more investigation.
+//
+template <class Policy>
+inline long double log1p(long double x, const Policy& pol)
+{
+   if(x < -1)
+      return policies::raise_domain_error<long double>(
+         "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol);
+   if(x == -1)
+      return -policies::raise_overflow_error<long double>(
+         "log1p<%1%>(%1%)", 0, pol);
+   long double u = 1+x;
+   if(u == 1.0) 
+      return x; 
+   else
+      return ::logl(u)*(x/(u-1.0));
+}
+#endif
+#endif
+
+template <class T>
+inline typename tools::promote_args<T>::type log1p(T x)
+{
+   return boost::math::log1p(x, policies::policy<>());
+}
+//
+// Compute log(1+x)-x:
+//
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type 
+   log1pmx(T x, const Policy& pol)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+   BOOST_MATH_STD_USING
+   static const char* function = "boost::math::log1pmx<%1%>(%1%)";
+
+   if(x < -1)
+      return policies::raise_domain_error<T>(
+         function, "log1pmx(x) requires x > -1, but got x = %1%.", x, pol);
+   if(x == -1)
+      return -policies::raise_overflow_error<T>(
+         function, 0, pol);
+
+   result_type a = abs(result_type(x));
+   if(a > result_type(0.95f))
+      return log(1 + result_type(x)) - result_type(x);
+   // Note that without numeric_limits specialisation support, 
+   // epsilon just returns zero, and our "optimisation" will always fail:
+   if(a < tools::epsilon<result_type>())
+      return -x * x / 2;
+   boost::math::detail::log1p_series<T> s(x);
+   s();
+   boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
+   T zero = 0;
+   T result = boost::math::tools::sum_series(s, policies::get_epsilon<T, Policy>(), max_iter, zero);
+#else
+   T result = boost::math::tools::sum_series(s, policies::get_epsilon<T, Policy>(), max_iter);
+#endif
+   policies::check_series_iterations<T>(function, max_iter, pol);
+   return result;
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type log1pmx(T x)
+{
+   return log1pmx(x, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // BOOST_MATH_LOG1P_INCLUDED
+
+
+
diff --git a/ThirdParty/boost/math/special_functions/next.hpp b/ThirdParty/boost/math/special_functions/next.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6b8305dfe1297cf5767892cbca8ecf9f8cf174d7
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/next.hpp
@@ -0,0 +1,858 @@
+//  (C) Copyright John Maddock 2008.
+//  Use, modification and distribution are subject to 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_SPECIAL_NEXT_HPP
+#define BOOST_MATH_SPECIAL_NEXT_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
+#include <boost/math/special_functions/sign.hpp>
+#include <boost/math/special_functions/trunc.hpp>
+
+#include <float.h>
+
+#if !defined(_CRAYC) && !defined(__CUDACC__) && (!defined(__GNUC__) || (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ > 3)))
+#if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(__SSE2__)
+#include "xmmintrin.h"
+#define BOOST_MATH_CHECK_SSE2
+#endif
+#endif
+
+namespace boost{ namespace math{
+
+   namespace concepts {
+
+      class real_concept;
+      class std_real_concept;
+
+   }
+
+namespace detail{
+
+template <class T>
+struct has_hidden_guard_digits;
+template <>
+struct has_hidden_guard_digits<float> : public boost::false_type {};
+template <>
+struct has_hidden_guard_digits<double> : public boost::false_type {};
+template <>
+struct has_hidden_guard_digits<long double> : public boost::false_type {};
+#ifdef BOOST_HAS_FLOAT128
+template <>
+struct has_hidden_guard_digits<__float128> : public boost::false_type {};
+#endif
+template <>
+struct has_hidden_guard_digits<boost::math::concepts::real_concept> : public boost::false_type {};
+template <>
+struct has_hidden_guard_digits<boost::math::concepts::std_real_concept> : public boost::false_type {};
+
+template <class T, bool b>
+struct has_hidden_guard_digits_10 : public boost::false_type {};
+template <class T>
+struct has_hidden_guard_digits_10<T, true> : public boost::integral_constant<bool, (std::numeric_limits<T>::digits10 != std::numeric_limits<T>::max_digits10)> {};
+
+template <class T>
+struct has_hidden_guard_digits 
+   : public has_hidden_guard_digits_10<T, 
+   std::numeric_limits<T>::is_specialized
+   && (std::numeric_limits<T>::radix == 10) >
+{};
+
+template <class T>
+inline const T& normalize_value(const T& val, const boost::false_type&) { return val; }
+template <class T>
+inline T normalize_value(const T& val, const boost::true_type&) 
+{
+   BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_specialized);
+   BOOST_STATIC_ASSERT(std::numeric_limits<T>::radix != 2);
+
+   boost::intmax_t shift = (boost::intmax_t)std::numeric_limits<T>::digits - (boost::intmax_t)ilogb(val) - 1;
+   T result = scalbn(val, shift);
+   result = round(result);
+   return scalbn(result, -shift); 
+}
+
+template <class T>
+inline T get_smallest_value(boost::true_type const&)
+{
+   //
+   // numeric_limits lies about denorms being present - particularly
+   // when this can be turned on or off at runtime, as is the case
+   // when using the SSE2 registers in DAZ or FTZ mode.
+   //
+   static const T m = std::numeric_limits<T>::denorm_min();
+#ifdef BOOST_MATH_CHECK_SSE2
+   return (_mm_getcsr() & (_MM_FLUSH_ZERO_ON | 0x40)) ? tools::min_value<T>() : m;;
+#else
+   return ((tools::min_value<T>() / 2) == 0) ? tools::min_value<T>() : m;
+#endif
+}
+
+template <class T>
+inline T get_smallest_value(boost::false_type const&)
+{
+   return tools::min_value<T>();
+}
+
+template <class T>
+inline T get_smallest_value()
+{
+#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1310)
+   return get_smallest_value<T>(boost::integral_constant<bool, std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::has_denorm == 1)>());
+#else
+   return get_smallest_value<T>(boost::integral_constant<bool, std::numeric_limits<T>::is_specialized && (std::numeric_limits<T>::has_denorm == std::denorm_present)>());
+#endif
+}
+
+//
+// Returns the smallest value that won't generate denorms when
+// we calculate the value of the least-significant-bit:
+//
+template <class T>
+T get_min_shift_value();
+
+template <class T>
+struct min_shift_initializer
+{
+   struct init
+   {
+      init()
+      {
+         do_init();
+      }
+      static void do_init()
+      {
+         get_min_shift_value<T>();
+      }
+      void force_instantiate()const{}
+   };
+   static const init initializer;
+   static void force_instantiate()
+   {
+      initializer.force_instantiate();
+   }
+};
+
+template <class T>
+const typename min_shift_initializer<T>::init min_shift_initializer<T>::initializer;
+
+template <class T>
+inline T calc_min_shifted(const boost::true_type&)
+{
+   BOOST_MATH_STD_USING
+   return ldexp(tools::min_value<T>(), tools::digits<T>() + 1);
+}
+template <class T>
+inline T calc_min_shifted(const boost::false_type&)
+{
+   BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_specialized);
+   BOOST_STATIC_ASSERT(std::numeric_limits<T>::radix != 2);
+
+   return scalbn(tools::min_value<T>(), std::numeric_limits<T>::digits + 1);
+}
+
+
+template <class T>
+inline T get_min_shift_value()
+{
+   static const T val = calc_min_shifted<T>(boost::integral_constant<bool, !std::numeric_limits<T>::is_specialized || std::numeric_limits<T>::radix == 2>());
+   min_shift_initializer<T>::force_instantiate();
+
+   return val;
+}
+
+template <class T, class Policy>
+T float_next_imp(const T& val, const boost::true_type&, const Policy& pol)
+{
+   BOOST_MATH_STD_USING
+   int expon;
+   static const char* function = "float_next<%1%>(%1%)";
+
+   int fpclass = (boost::math::fpclassify)(val);
+
+   if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE))
+   {
+      if(val < 0)
+         return -tools::max_value<T>();
+      return policies::raise_domain_error<T>(
+         function,
+         "Argument must be finite, but got %1%", val, pol);
+   }
+
+   if(val >= tools::max_value<T>())
+      return policies::raise_overflow_error<T>(function, 0, pol);
+
+   if(val == 0)
+      return detail::get_smallest_value<T>();
+
+   if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value<T>()) && (val != -tools::min_value<T>()))
+   {
+      //
+      // Special case: if the value of the least significant bit is a denorm, and the result
+      // would not be a denorm, then shift the input, increment, and shift back.
+      // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set.
+      //
+      return ldexp(float_next(T(ldexp(val, 2 * tools::digits<T>())), pol), -2 * tools::digits<T>());
+   }
+
+   if(-0.5f == frexp(val, &expon))
+      --expon; // reduce exponent when val is a power of two, and negative.
+   T diff = ldexp(T(1), expon - tools::digits<T>());
+   if(diff == 0)
+      diff = detail::get_smallest_value<T>();
+   return val + diff;
+} // float_next_imp
+//
+// Special version for some base other than 2:
+//
+template <class T, class Policy>
+T float_next_imp(const T& val, const boost::false_type&, const Policy& pol)
+{
+   BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_specialized);
+   BOOST_STATIC_ASSERT(std::numeric_limits<T>::radix != 2);
+
+   BOOST_MATH_STD_USING
+   boost::intmax_t expon;
+   static const char* function = "float_next<%1%>(%1%)";
+
+   int fpclass = (boost::math::fpclassify)(val);
+
+   if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE))
+   {
+      if(val < 0)
+         return -tools::max_value<T>();
+      return policies::raise_domain_error<T>(
+         function,
+         "Argument must be finite, but got %1%", val, pol);
+   }
+
+   if(val >= tools::max_value<T>())
+      return policies::raise_overflow_error<T>(function, 0, pol);
+
+   if(val == 0)
+      return detail::get_smallest_value<T>();
+
+   if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value<T>()) && (val != -tools::min_value<T>()))
+   {
+      //
+      // Special case: if the value of the least significant bit is a denorm, and the result
+      // would not be a denorm, then shift the input, increment, and shift back.
+      // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set.
+      //
+      return scalbn(float_next(T(scalbn(val, 2 * std::numeric_limits<T>::digits)), pol), -2 * std::numeric_limits<T>::digits);
+   }
+
+   expon = 1 + ilogb(val);
+   if(-1 == scalbn(val, -expon) * std::numeric_limits<T>::radix)
+      --expon; // reduce exponent when val is a power of base, and negative.
+   T diff = scalbn(T(1), expon - std::numeric_limits<T>::digits);
+   if(diff == 0)
+      diff = detail::get_smallest_value<T>();
+   return val + diff;
+} // float_next_imp
+
+} // namespace detail
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type float_next(const T& val, const Policy& pol)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+   return detail::float_next_imp(detail::normalize_value(static_cast<result_type>(val), typename detail::has_hidden_guard_digits<result_type>::type()), boost::integral_constant<bool, !std::numeric_limits<result_type>::is_specialized || (std::numeric_limits<result_type>::radix == 2)>(), pol);
+}
+
+#if 0 //def BOOST_MSVC
+//
+// We used to use ::_nextafter here, but doing so fails when using
+// the SSE2 registers if the FTZ or DAZ flags are set, so use our own
+// - albeit slower - code instead as at least that gives the correct answer.
+//
+template <class Policy>
+inline double float_next(const double& val, const Policy& pol)
+{
+   static const char* function = "float_next<%1%>(%1%)";
+
+   if(!(boost::math::isfinite)(val) && (val > 0))
+      return policies::raise_domain_error<double>(
+         function,
+         "Argument must be finite, but got %1%", val, pol);
+
+   if(val >= tools::max_value<double>())
+      return policies::raise_overflow_error<double>(function, 0, pol);
+
+   return ::_nextafter(val, tools::max_value<double>());
+}
+#endif
+
+template <class T>
+inline typename tools::promote_args<T>::type float_next(const T& val)
+{
+   return float_next(val, policies::policy<>());
+}
+
+namespace detail{
+
+template <class T, class Policy>
+T float_prior_imp(const T& val, const boost::true_type&, const Policy& pol)
+{
+   BOOST_MATH_STD_USING
+   int expon;
+   static const char* function = "float_prior<%1%>(%1%)";
+
+   int fpclass = (boost::math::fpclassify)(val);
+
+   if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE))
+   {
+      if(val > 0)
+         return tools::max_value<T>();
+      return policies::raise_domain_error<T>(
+         function,
+         "Argument must be finite, but got %1%", val, pol);
+   }
+
+   if(val <= -tools::max_value<T>())
+      return -policies::raise_overflow_error<T>(function, 0, pol);
+
+   if(val == 0)
+      return -detail::get_smallest_value<T>();
+
+   if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value<T>()) && (val != tools::min_value<T>()))
+   {
+      //
+      // Special case: if the value of the least significant bit is a denorm, and the result
+      // would not be a denorm, then shift the input, increment, and shift back.
+      // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set.
+      //
+      return ldexp(float_prior(T(ldexp(val, 2 * tools::digits<T>())), pol), -2 * tools::digits<T>());
+   }
+
+   T remain = frexp(val, &expon);
+   if(remain == 0.5f)
+      --expon; // when val is a power of two we must reduce the exponent
+   T diff = ldexp(T(1), expon - tools::digits<T>());
+   if(diff == 0)
+      diff = detail::get_smallest_value<T>();
+   return val - diff;
+} // float_prior_imp
+//
+// Special version for bases other than 2:
+//
+template <class T, class Policy>
+T float_prior_imp(const T& val, const boost::false_type&, const Policy& pol)
+{
+   BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_specialized);
+   BOOST_STATIC_ASSERT(std::numeric_limits<T>::radix != 2);
+
+   BOOST_MATH_STD_USING
+   boost::intmax_t expon;
+   static const char* function = "float_prior<%1%>(%1%)";
+
+   int fpclass = (boost::math::fpclassify)(val);
+
+   if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE))
+   {
+      if(val > 0)
+         return tools::max_value<T>();
+      return policies::raise_domain_error<T>(
+         function,
+         "Argument must be finite, but got %1%", val, pol);
+   }
+
+   if(val <= -tools::max_value<T>())
+      return -policies::raise_overflow_error<T>(function, 0, pol);
+
+   if(val == 0)
+      return -detail::get_smallest_value<T>();
+
+   if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value<T>()) && (val != tools::min_value<T>()))
+   {
+      //
+      // Special case: if the value of the least significant bit is a denorm, and the result
+      // would not be a denorm, then shift the input, increment, and shift back.
+      // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set.
+      //
+      return scalbn(float_prior(T(scalbn(val, 2 * std::numeric_limits<T>::digits)), pol), -2 * std::numeric_limits<T>::digits);
+   }
+
+   expon = 1 + ilogb(val);
+   T remain = scalbn(val, -expon);
+   if(remain * std::numeric_limits<T>::radix == 1)
+      --expon; // when val is a power of two we must reduce the exponent
+   T diff = scalbn(T(1), expon - std::numeric_limits<T>::digits);
+   if(diff == 0)
+      diff = detail::get_smallest_value<T>();
+   return val - diff;
+} // float_prior_imp
+
+} // namespace detail
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type float_prior(const T& val, const Policy& pol)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+   return detail::float_prior_imp(detail::normalize_value(static_cast<result_type>(val), typename detail::has_hidden_guard_digits<result_type>::type()), boost::integral_constant<bool, !std::numeric_limits<result_type>::is_specialized || (std::numeric_limits<result_type>::radix == 2)>(), pol);
+}
+
+#if 0 //def BOOST_MSVC
+//
+// We used to use ::_nextafter here, but doing so fails when using
+// the SSE2 registers if the FTZ or DAZ flags are set, so use our own
+// - albeit slower - code instead as at least that gives the correct answer.
+//
+template <class Policy>
+inline double float_prior(const double& val, const Policy& pol)
+{
+   static const char* function = "float_prior<%1%>(%1%)";
+
+   if(!(boost::math::isfinite)(val) && (val < 0))
+      return policies::raise_domain_error<double>(
+         function,
+         "Argument must be finite, but got %1%", val, pol);
+
+   if(val <= -tools::max_value<double>())
+      return -policies::raise_overflow_error<double>(function, 0, pol);
+
+   return ::_nextafter(val, -tools::max_value<double>());
+}
+#endif
+
+template <class T>
+inline typename tools::promote_args<T>::type float_prior(const T& val)
+{
+   return float_prior(val, policies::policy<>());
+}
+
+template <class T, class U, class Policy>
+inline typename tools::promote_args<T, U>::type nextafter(const T& val, const U& direction, const Policy& pol)
+{
+   typedef typename tools::promote_args<T, U>::type result_type;
+   return val < direction ? boost::math::float_next<result_type>(val, pol) : val == direction ? val : boost::math::float_prior<result_type>(val, pol);
+}
+
+template <class T, class U>
+inline typename tools::promote_args<T, U>::type nextafter(const T& val, const U& direction)
+{
+   return nextafter(val, direction, policies::policy<>());
+}
+
+namespace detail{
+
+template <class T, class Policy>
+T float_distance_imp(const T& a, const T& b, const boost::true_type&, const Policy& pol)
+{
+   BOOST_MATH_STD_USING
+   //
+   // Error handling:
+   //
+   static const char* function = "float_distance<%1%>(%1%, %1%)";
+   if(!(boost::math::isfinite)(a))
+      return policies::raise_domain_error<T>(
+         function,
+         "Argument a must be finite, but got %1%", a, pol);
+   if(!(boost::math::isfinite)(b))
+      return policies::raise_domain_error<T>(
+         function,
+         "Argument b must be finite, but got %1%", b, pol);
+   //
+   // Special cases:
+   //
+   if(a > b)
+      return -float_distance(b, a, pol);
+   if(a == b)
+      return T(0);
+   if(a == 0)
+      return 1 + fabs(float_distance(static_cast<T>((b < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), b, pol));
+   if(b == 0)
+      return 1 + fabs(float_distance(static_cast<T>((a < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), a, pol));
+   if(boost::math::sign(a) != boost::math::sign(b))
+      return 2 + fabs(float_distance(static_cast<T>((b < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), b, pol))
+         + fabs(float_distance(static_cast<T>((a < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), a, pol));
+   //
+   // By the time we get here, both a and b must have the same sign, we want
+   // b > a and both positive for the following logic:
+   //
+   if(a < 0)
+      return float_distance(static_cast<T>(-b), static_cast<T>(-a), pol);
+
+   BOOST_ASSERT(a >= 0);
+   BOOST_ASSERT(b >= a);
+
+   int expon;
+   //
+   // Note that if a is a denorm then the usual formula fails
+   // because we actually have fewer than tools::digits<T>()
+   // significant bits in the representation:
+   //
+   (void)frexp(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) ? tools::min_value<T>() : a, &expon);
+   T upper = ldexp(T(1), expon);
+   T result = T(0);
+   //
+   // If b is greater than upper, then we *must* split the calculation
+   // as the size of the ULP changes with each order of magnitude change:
+   //
+   if(b > upper)
+   {
+      int expon2;
+      (void)frexp(b, &expon2);
+      T upper2 = ldexp(T(0.5), expon2);
+      result = float_distance(upper2, b);
+      result += (expon2 - expon - 1) * ldexp(T(1), tools::digits<T>() - 1);
+   }
+   //
+   // Use compensated double-double addition to avoid rounding
+   // errors in the subtraction:
+   //
+   expon = tools::digits<T>() - expon;
+   T mb, x, y, z;
+   if(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) || (b - a < tools::min_value<T>()))
+   {
+      //
+      // Special case - either one end of the range is a denormal, or else the difference is.
+      // The regular code will fail if we're using the SSE2 registers on Intel and either
+      // the FTZ or DAZ flags are set.
+      //
+      T a2 = ldexp(a, tools::digits<T>());
+      T b2 = ldexp(b, tools::digits<T>());
+      mb = -(std::min)(T(ldexp(upper, tools::digits<T>())), b2);
+      x = a2 + mb;
+      z = x - a2;
+      y = (a2 - (x - z)) + (mb - z);
+
+      expon -= tools::digits<T>();
+   }
+   else
+   {
+      mb = -(std::min)(upper, b);
+      x = a + mb;
+      z = x - a;
+      y = (a - (x - z)) + (mb - z);
+   }
+   if(x < 0)
+   {
+      x = -x;
+      y = -y;
+   }
+   result += ldexp(x, expon) + ldexp(y, expon);
+   //
+   // Result must be an integer:
+   //
+   BOOST_ASSERT(result == floor(result));
+   return result;
+} // float_distance_imp
+//
+// Special versions for bases other than 2:
+//
+template <class T, class Policy>
+T float_distance_imp(const T& a, const T& b, const boost::false_type&, const Policy& pol)
+{
+   BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_specialized);
+   BOOST_STATIC_ASSERT(std::numeric_limits<T>::radix != 2);
+
+   BOOST_MATH_STD_USING
+   //
+   // Error handling:
+   //
+   static const char* function = "float_distance<%1%>(%1%, %1%)";
+   if(!(boost::math::isfinite)(a))
+      return policies::raise_domain_error<T>(
+         function,
+         "Argument a must be finite, but got %1%", a, pol);
+   if(!(boost::math::isfinite)(b))
+      return policies::raise_domain_error<T>(
+         function,
+         "Argument b must be finite, but got %1%", b, pol);
+   //
+   // Special cases:
+   //
+   if(a > b)
+      return -float_distance(b, a, pol);
+   if(a == b)
+      return T(0);
+   if(a == 0)
+      return 1 + fabs(float_distance(static_cast<T>((b < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), b, pol));
+   if(b == 0)
+      return 1 + fabs(float_distance(static_cast<T>((a < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), a, pol));
+   if(boost::math::sign(a) != boost::math::sign(b))
+      return 2 + fabs(float_distance(static_cast<T>((b < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), b, pol))
+         + fabs(float_distance(static_cast<T>((a < 0) ? T(-detail::get_smallest_value<T>()) : detail::get_smallest_value<T>()), a, pol));
+   //
+   // By the time we get here, both a and b must have the same sign, we want
+   // b > a and both positive for the following logic:
+   //
+   if(a < 0)
+      return float_distance(static_cast<T>(-b), static_cast<T>(-a), pol);
+
+   BOOST_ASSERT(a >= 0);
+   BOOST_ASSERT(b >= a);
+
+   boost::intmax_t expon;
+   //
+   // Note that if a is a denorm then the usual formula fails
+   // because we actually have fewer than tools::digits<T>()
+   // significant bits in the representation:
+   //
+   expon = 1 + ilogb(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) ? tools::min_value<T>() : a);
+   T upper = scalbn(T(1), expon);
+   T result = T(0);
+   //
+   // If b is greater than upper, then we *must* split the calculation
+   // as the size of the ULP changes with each order of magnitude change:
+   //
+   if(b > upper)
+   {
+      boost::intmax_t expon2 = 1 + ilogb(b);
+      T upper2 = scalbn(T(1), expon2 - 1);
+      result = float_distance(upper2, b);
+      result += (expon2 - expon - 1) * scalbn(T(1), std::numeric_limits<T>::digits - 1);
+   }
+   //
+   // Use compensated double-double addition to avoid rounding
+   // errors in the subtraction:
+   //
+   expon = std::numeric_limits<T>::digits - expon;
+   T mb, x, y, z;
+   if(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) || (b - a < tools::min_value<T>()))
+   {
+      //
+      // Special case - either one end of the range is a denormal, or else the difference is.
+      // The regular code will fail if we're using the SSE2 registers on Intel and either
+      // the FTZ or DAZ flags are set.
+      //
+      T a2 = scalbn(a, std::numeric_limits<T>::digits);
+      T b2 = scalbn(b, std::numeric_limits<T>::digits);
+      mb = -(std::min)(T(scalbn(upper, std::numeric_limits<T>::digits)), b2);
+      x = a2 + mb;
+      z = x - a2;
+      y = (a2 - (x - z)) + (mb - z);
+
+      expon -= std::numeric_limits<T>::digits;
+   }
+   else
+   {
+      mb = -(std::min)(upper, b);
+      x = a + mb;
+      z = x - a;
+      y = (a - (x - z)) + (mb - z);
+   }
+   if(x < 0)
+   {
+      x = -x;
+      y = -y;
+   }
+   result += scalbn(x, expon) + scalbn(y, expon);
+   //
+   // Result must be an integer:
+   //
+   BOOST_ASSERT(result == floor(result));
+   return result;
+} // float_distance_imp
+
+} // namespace detail
+
+template <class T, class U, class Policy>
+inline typename tools::promote_args<T, U>::type float_distance(const T& a, const U& b, const Policy& pol)
+{
+   typedef typename tools::promote_args<T, U>::type result_type;
+   return detail::float_distance_imp(detail::normalize_value(static_cast<result_type>(a), typename detail::has_hidden_guard_digits<result_type>::type()), detail::normalize_value(static_cast<result_type>(b), typename detail::has_hidden_guard_digits<result_type>::type()), boost::integral_constant<bool, !std::numeric_limits<result_type>::is_specialized || (std::numeric_limits<result_type>::radix == 2)>(), pol);
+}
+
+template <class T, class U>
+typename tools::promote_args<T, U>::type float_distance(const T& a, const U& b)
+{
+   return boost::math::float_distance(a, b, policies::policy<>());
+}
+
+namespace detail{
+
+template <class T, class Policy>
+T float_advance_imp(T val, int distance, const boost::true_type&, const Policy& pol)
+{
+   BOOST_MATH_STD_USING
+   //
+   // Error handling:
+   //
+   static const char* function = "float_advance<%1%>(%1%, int)";
+
+   int fpclass = (boost::math::fpclassify)(val);
+
+   if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE))
+      return policies::raise_domain_error<T>(
+         function,
+         "Argument val must be finite, but got %1%", val, pol);
+
+   if(val < 0)
+      return -float_advance(-val, -distance, pol);
+   if(distance == 0)
+      return val;
+   if(distance == 1)
+      return float_next(val, pol);
+   if(distance == -1)
+      return float_prior(val, pol);
+
+   if(fabs(val) < detail::get_min_shift_value<T>())
+   {
+      //
+      // Special case: if the value of the least significant bit is a denorm,
+      // implement in terms of float_next/float_prior.
+      // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set.
+      //
+      if(distance > 0)
+      {
+         do{ val = float_next(val, pol); } while(--distance);
+      }
+      else
+      {
+         do{ val = float_prior(val, pol); } while(++distance);
+      }
+      return val;
+   }
+
+   int expon;
+   (void)frexp(val, &expon);
+   T limit = ldexp((distance < 0 ? T(0.5f) : T(1)), expon);
+   if(val <= tools::min_value<T>())
+   {
+      limit = sign(T(distance)) * tools::min_value<T>();
+   }
+   T limit_distance = float_distance(val, limit);
+   while(fabs(limit_distance) < abs(distance))
+   {
+      distance -= itrunc(limit_distance);
+      val = limit;
+      if(distance < 0)
+      {
+         limit /= 2;
+         expon--;
+      }
+      else
+      {
+         limit *= 2;
+         expon++;
+      }
+      limit_distance = float_distance(val, limit);
+      if(distance && (limit_distance == 0))
+      {
+         return policies::raise_evaluation_error<T>(function, "Internal logic failed while trying to increment floating point value %1%: most likely your FPU is in non-IEEE conforming mode.", val, pol);
+      }
+   }
+   if((0.5f == frexp(val, &expon)) && (distance < 0))
+      --expon;
+   T diff = 0;
+   if(val != 0)
+      diff = distance * ldexp(T(1), expon - tools::digits<T>());
+   if(diff == 0)
+      diff = distance * detail::get_smallest_value<T>();
+   return val += diff;
+} // float_advance_imp
+//
+// Special version for bases other than 2:
+//
+template <class T, class Policy>
+T float_advance_imp(T val, int distance, const boost::false_type&, const Policy& pol)
+{
+   BOOST_STATIC_ASSERT(std::numeric_limits<T>::is_specialized);
+   BOOST_STATIC_ASSERT(std::numeric_limits<T>::radix != 2);
+
+   BOOST_MATH_STD_USING
+   //
+   // Error handling:
+   //
+   static const char* function = "float_advance<%1%>(%1%, int)";
+
+   int fpclass = (boost::math::fpclassify)(val);
+
+   if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE))
+      return policies::raise_domain_error<T>(
+         function,
+         "Argument val must be finite, but got %1%", val, pol);
+
+   if(val < 0)
+      return -float_advance(-val, -distance, pol);
+   if(distance == 0)
+      return val;
+   if(distance == 1)
+      return float_next(val, pol);
+   if(distance == -1)
+      return float_prior(val, pol);
+
+   if(fabs(val) < detail::get_min_shift_value<T>())
+   {
+      //
+      // Special case: if the value of the least significant bit is a denorm,
+      // implement in terms of float_next/float_prior.
+      // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set.
+      //
+      if(distance > 0)
+      {
+         do{ val = float_next(val, pol); } while(--distance);
+      }
+      else
+      {
+         do{ val = float_prior(val, pol); } while(++distance);
+      }
+      return val;
+   }
+
+   boost::intmax_t expon = 1 + ilogb(val);
+   T limit = scalbn(T(1), distance < 0 ? expon - 1 : expon);
+   if(val <= tools::min_value<T>())
+   {
+      limit = sign(T(distance)) * tools::min_value<T>();
+   }
+   T limit_distance = float_distance(val, limit);
+   while(fabs(limit_distance) < abs(distance))
+   {
+      distance -= itrunc(limit_distance);
+      val = limit;
+      if(distance < 0)
+      {
+         limit /= std::numeric_limits<T>::radix;
+         expon--;
+      }
+      else
+      {
+         limit *= std::numeric_limits<T>::radix;
+         expon++;
+      }
+      limit_distance = float_distance(val, limit);
+      if(distance && (limit_distance == 0))
+      {
+         return policies::raise_evaluation_error<T>(function, "Internal logic failed while trying to increment floating point value %1%: most likely your FPU is in non-IEEE conforming mode.", val, pol);
+      }
+   }
+   /*expon = 1 + ilogb(val);
+   if((1 == scalbn(val, 1 + expon)) && (distance < 0))
+      --expon;*/
+   T diff = 0;
+   if(val != 0)
+      diff = distance * scalbn(T(1), expon - std::numeric_limits<T>::digits);
+   if(diff == 0)
+      diff = distance * detail::get_smallest_value<T>();
+   return val += diff;
+} // float_advance_imp
+
+} // namespace detail
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type float_advance(T val, int distance, const Policy& pol)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+   return detail::float_advance_imp(detail::normalize_value(static_cast<result_type>(val), typename detail::has_hidden_guard_digits<result_type>::type()), distance, boost::integral_constant<bool, !std::numeric_limits<result_type>::is_specialized || (std::numeric_limits<result_type>::radix == 2)>(), pol);
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type float_advance(const T& val, int distance)
+{
+   return boost::math::float_advance(val, distance, policies::policy<>());
+}
+
+}} // boost math namespaces
+
+#endif // BOOST_MATH_SPECIAL_NEXT_HPP
+
diff --git a/ThirdParty/boost/math/special_functions/polygamma.hpp b/ThirdParty/boost/math/special_functions/polygamma.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6b7815d5e07fdebe558bc515836bb137937f5509
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/polygamma.hpp
@@ -0,0 +1,83 @@
+
+///////////////////////////////////////////////////////////////////////////////
+//  Copyright 2013 Nikhar Agrawal
+//  Copyright 2013 Christopher Kormanyos
+//  Copyright 2014 John Maddock
+//  Copyright 2013 Paul Bristow
+//  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_POLYGAMMA_2013_07_30_HPP_
+  #define _BOOST_POLYGAMMA_2013_07_30_HPP_
+
+#include <boost/math/special_functions/factorials.hpp>
+#include <boost/math/special_functions/detail/polygamma.hpp>
+#include <boost/math/special_functions/trigamma.hpp>
+
+namespace boost { namespace math {
+
+  
+  template<class T, class Policy>
+  inline typename tools::promote_args<T>::type polygamma(const int n, T x, const Policy& pol)
+  {
+     //
+     // Filter off special cases right at the start:
+     //
+     if(n == 0)
+        return boost::math::digamma(x, pol);
+     if(n == 1)
+        return boost::math::trigamma(x, pol);
+     //
+     // We've found some standard library functions to misbehave if any FPU exception flags
+     // are set prior to their call, this code will clear those flags, then reset them
+     // on exit:
+     //
+     BOOST_FPU_EXCEPTION_GUARD
+     //
+     // The type of the result - the common type of T and U after
+     // any integer types have been promoted to double:
+     //
+     typedef typename tools::promote_args<T>::type result_type;
+     //
+     // The type used for the calculation.  This may be a wider type than
+     // the result in order to ensure full precision:
+     //
+     typedef typename policies::evaluation<result_type, Policy>::type value_type;
+     //
+     // The type of the policy to forward to the actual implementation.
+     // We disable promotion of float and double as that's [possibly]
+     // happened already in the line above.  Also reset to the default
+     // any policies we don't use (reduces code bloat if we're called
+     // multiple times with differing policies we don't actually use).
+     // Also normalise the type, again to reduce code bloat in case we're
+     // called multiple times with functionally identical policies that happen
+     // to be different types.
+     //
+     typedef typename policies::normalise<
+        Policy,
+        policies::promote_float<false>,
+        policies::promote_double<false>,
+        policies::discrete_quantile<>,
+        policies::assert_undefined<> >::type forwarding_policy;
+     //
+     // Whew.  Now we can make the actual call to the implementation.
+     // Arguments are explicitly cast to the evaluation type, and the result
+     // passed through checked_narrowing_cast which handles things like overflow
+     // according to the policy passed:
+     //
+     return policies::checked_narrowing_cast<result_type, forwarding_policy>(
+        detail::polygamma_imp(n, static_cast<value_type>(x), forwarding_policy()),
+        "boost::math::polygamma<%1%>(int, %1%)");
+  }
+
+  template<class T>
+  inline typename tools::promote_args<T>::type polygamma(const int n, T x)
+  {
+      return boost::math::polygamma(n, x, policies::policy<>());
+  }
+
+} } // namespace boost::math
+
+#endif // _BOOST_BERNOULLI_2013_05_30_HPP_
+
diff --git a/ThirdParty/boost/math/special_functions/pow.hpp b/ThirdParty/boost/math/special_functions/pow.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9c92116acd02166e89401ece825321ba06161dc7
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/pow.hpp
@@ -0,0 +1,148 @@
+//   Boost pow.hpp header file
+//   Computes a power with exponent known at compile-time
+
+//  (C) Copyright Bruno Lalande 2008.
+//  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)
+
+//  See http://www.boost.org for updates, documentation, and revision history.
+
+
+#ifndef BOOST_MATH_POW_HPP
+#define BOOST_MATH_POW_HPP
+
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/policies/policy.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/tools/promotion.hpp>
+#include <boost/mpl/greater_equal.hpp>
+
+
+namespace boost {
+namespace math {
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4702) // Unreachable code, only triggered in release mode and /W4
+#endif
+
+namespace detail {
+
+
+template <int N, int M = N%2>
+struct positive_power
+{
+    template <typename T>
+    static T result(T base)
+    {
+        T power = positive_power<N/2>::result(base);
+        return power * power;
+    }
+};
+
+template <int N>
+struct positive_power<N, 1>
+{
+    template <typename T>
+    static T result(T base)
+    {
+        T power = positive_power<N/2>::result(base);
+        return base * power * power;
+    }
+};
+
+template <>
+struct positive_power<1, 1>
+{
+    template <typename T>
+    static T result(T base){ return base; }
+};
+
+
+template <int N, bool>
+struct power_if_positive
+{
+    template <typename T, class Policy>
+    static T result(T base, const Policy&)
+    { return positive_power<N>::result(base); }
+};
+
+template <int N>
+struct power_if_positive<N, false>
+{
+    template <typename T, class Policy>
+    static T result(T base, const Policy& policy)
+    {
+        if (base == 0)
+        {
+            return policies::raise_overflow_error<T>(
+                       "boost::math::pow(%1%)",
+                       "Attempted to compute a negative power of 0",
+                       policy
+                   );
+        }
+
+        return T(1) / positive_power<-N>::result(base);
+    }
+};
+
+template <>
+struct power_if_positive<0, true>
+{
+    template <typename T, class Policy>
+    static T result(T base, const Policy& policy)
+    {
+        if (base == 0)
+        {
+            return policies::raise_indeterminate_result_error<T>(
+                       "boost::math::pow(%1%)",
+                       "The result of pow<0>(%1%) is undetermined",
+                       base,
+                       T(1),
+                       policy
+                   );
+        }
+
+        return T(1);
+    }
+};
+
+
+template <int N>
+struct select_power_if_positive
+{
+    typedef typename mpl::greater_equal<
+                         boost::integral_constant<int, N>,
+                         boost::integral_constant<int, 0>
+                     >::type is_positive;
+
+    typedef power_if_positive<N, is_positive::value> type;
+};
+
+
+}  // namespace detail
+
+
+template <int N, typename T, class Policy>
+inline typename tools::promote_args<T>::type pow(T base, const Policy& policy)
+{ 
+   typedef typename tools::promote_args<T>::type result_type;
+   return detail::select_power_if_positive<N>::type::result(static_cast<result_type>(base), policy); 
+}
+
+
+template <int N, typename T>
+inline typename tools::promote_args<T>::type pow(T base)
+{ return pow<N>(base, policies::policy<>()); }
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+}  // namespace math
+}  // namespace boost
+
+
+#endif
diff --git a/ThirdParty/boost/math/special_functions/powm1.hpp b/ThirdParty/boost/math/special_functions/powm1.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..37db8746c8aba3c40edcb4c6153cec724a21b202
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/powm1.hpp
@@ -0,0 +1,84 @@
+//  (C) Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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_POWM1
+#define BOOST_MATH_POWM1
+
+#ifdef _MSC_VER
+#pragma once
+#pragma warning(push)
+#pragma warning(disable:4702) // Unreachable code (release mode only warning)
+#endif
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/special_functions/log1p.hpp>
+#include <boost/math/special_functions/expm1.hpp>
+#include <boost/math/special_functions/trunc.hpp>
+#include <boost/assert.hpp>
+
+namespace boost{ namespace math{ namespace detail{
+
+template <class T, class Policy>
+inline T powm1_imp(const T x, const T y, const Policy& pol)
+{
+   BOOST_MATH_STD_USING
+   static const char* function = "boost::math::powm1<%1%>(%1%, %1%)";
+
+   if (x > 0)
+   {
+      if ((fabs(y * (x - 1)) < 0.5) || (fabs(y) < 0.2))
+      {
+         // We don't have any good/quick approximation for log(x) * y
+         // so just try it and see:
+         T l = y * log(x);
+         if (l < 0.5)
+            return boost::math::expm1(l);
+         if (l > boost::math::tools::log_max_value<T>())
+            return boost::math::policies::raise_overflow_error<T>(function, 0, pol);
+         // fall through....
+      }
+   }
+   else
+   {
+      // y had better be an integer:
+      if (boost::math::trunc(y) != y)
+         return boost::math::policies::raise_domain_error<T>(function, "For non-integral exponent, expected base > 0 but got %1%", x, pol);
+      if (boost::math::trunc(y / 2) == y / 2)
+         return powm1_imp(T(-x), y, pol);
+   }
+   return pow(x, y) - 1;
+}
+
+} // detail
+
+template <class T1, class T2>
+inline typename tools::promote_args<T1, T2>::type 
+   powm1(const T1 a, const T2 z)
+{
+   typedef typename tools::promote_args<T1, T2>::type result_type;
+   return detail::powm1_imp(static_cast<result_type>(a), static_cast<result_type>(z), policies::policy<>());
+}
+
+template <class T1, class T2, class Policy>
+inline typename tools::promote_args<T1, T2>::type 
+   powm1(const T1 a, const T2 z, const Policy& pol)
+{
+   typedef typename tools::promote_args<T1, T2>::type result_type;
+   return detail::powm1_imp(static_cast<result_type>(a), static_cast<result_type>(z), pol);
+}
+
+} // namespace math
+} // namespace boost
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // BOOST_MATH_POWM1
+
+
+
+
+
diff --git a/ThirdParty/boost/math/special_functions/sin_pi.hpp b/ThirdParty/boost/math/special_functions/sin_pi.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c55c4ff7929bd181097207cb8e85da113fa0e4f3
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/sin_pi.hpp
@@ -0,0 +1,81 @@
+//  Copyright (c) 2007 John Maddock
+//  Use, modification and distribution are subject to 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_SIN_PI_HPP
+#define BOOST_MATH_SIN_PI_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/math/tools/config.hpp>
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/special_functions/trunc.hpp>
+#include <boost/math/tools/promotion.hpp>
+#include <boost/math/constants/constants.hpp>
+
+namespace boost{ namespace math{ namespace detail{
+
+template <class T, class Policy>
+inline T sin_pi_imp(T x, const Policy& pol)
+{
+   BOOST_MATH_STD_USING // ADL of std names
+   if(x < 0)
+      return -sin_pi_imp(T(-x), pol);
+   // sin of pi*x:
+   bool invert;
+   if(x < 0.5)
+      return sin(constants::pi<T>() * x);
+   if(x < 1)
+   {
+      invert = true;
+      x = -x;
+   }
+   else
+      invert = false;
+
+   T rem = floor(x);
+   if(iconvert(rem, pol) & 1)
+      invert = !invert;
+   rem = x - rem;
+   if(rem > 0.5f)
+      rem = 1 - rem;
+   if(rem == 0.5f)
+      return static_cast<T>(invert ? -1 : 1);
+   
+   rem = sin(constants::pi<T>() * rem);
+   return invert ? T(-rem) : rem;
+}
+
+} // namespace detail
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type sin_pi(T x, const Policy&)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   typedef typename policies::normalise<
+      Policy,
+      policies::promote_float<false>,
+      policies::promote_double<false>,
+      policies::discrete_quantile<>,
+      policies::assert_undefined<>,
+      // We want to ignore overflows since the result is in [-1,1] and the 
+      // check slows the code down considerably.
+      policies::overflow_error<policies::ignore_error> >::type forwarding_policy;
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(boost::math::detail::sin_pi_imp<value_type>(x, forwarding_policy()), "sin_pi");
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type sin_pi(T x)
+{
+   return boost::math::sin_pi(x, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+#endif
+
diff --git a/ThirdParty/boost/math/special_functions/sqrt1pm1.hpp b/ThirdParty/boost/math/special_functions/sqrt1pm1.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..293a9d97b312c8d2141dab4a9fce9ba95931f167
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/sqrt1pm1.hpp
@@ -0,0 +1,48 @@
+//  (C) Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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_SQRT1PM1
+#define BOOST_MATH_SQRT1PM1
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/special_functions/log1p.hpp>
+#include <boost/math/special_functions/expm1.hpp>
+
+//
+// This algorithm computes sqrt(1+x)-1 for small x:
+//
+
+namespace boost{ namespace math{
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type sqrt1pm1(const T& val, const Policy& pol)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+   BOOST_MATH_STD_USING
+
+   if(fabs(result_type(val)) > 0.75)
+      return sqrt(1 + result_type(val)) - 1;
+   return boost::math::expm1(boost::math::log1p(val, pol) / 2, pol);
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type sqrt1pm1(const T& val)
+{
+   return sqrt1pm1(val, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_SQRT1PM1
+
+
+
+
+
diff --git a/ThirdParty/boost/math/special_functions/trigamma.hpp b/ThirdParty/boost/math/special_functions/trigamma.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..943302dd5f28d39a87b2750725bce9dc7502c5c4
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/trigamma.hpp
@@ -0,0 +1,468 @@
+//  (C) Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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_SF_TRIGAMMA_HPP
+#define BOOST_MATH_SF_TRIGAMMA_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/tools/rational.hpp>
+#include <boost/math/tools/series.hpp>
+#include <boost/math/tools/promotion.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/constants/constants.hpp>
+#include <boost/mpl/comparison.hpp>
+#include <boost/math/tools/big_constant.hpp>
+#include <boost/math/special_functions/polygamma.hpp>
+
+#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128)
+//
+// This is the only way we can avoid
+// warning: non-standard suffix on floating constant [-Wpedantic]
+// when building with -Wall -pedantic.  Neither __extension__
+// nor #pragma diagnostic ignored work :(
+//
+#pragma GCC system_header
+#endif
+
+namespace boost{
+namespace math{
+namespace detail{
+
+template<class T, class Policy>
+T polygamma_imp(const int n, T x, const Policy &pol);
+
+template <class T, class Policy>
+T trigamma_prec(T x, const boost::integral_constant<int, 53>*, const Policy&)
+{
+   // Max error in interpolated form: 3.736e-017
+   static const T offset = BOOST_MATH_BIG_CONSTANT(T, 53, 2.1093254089355469);
+   static const T P_1_2[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 53, -1.1093280605946045),
+      BOOST_MATH_BIG_CONSTANT(T, 53, -3.8310674472619321),
+      BOOST_MATH_BIG_CONSTANT(T, 53, -3.3703848401898283),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 0.28080574467981213),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 1.6638069578676164),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 0.64468386819102836),
+   };
+   static const T Q_1_2[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 53, 1.0),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 3.4535389668541151),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 4.5208926987851437),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 2.7012734178351534),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 0.64468798399785611),
+      BOOST_MATH_BIG_CONSTANT(T, 53, -0.20314516859987728e-6),
+   };
+   // Max error in interpolated form: 1.159e-017
+   static const T P_2_4[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 53, -0.13803835004508849e-7),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 0.50000049158540261),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 1.6077979838469348),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 2.5645435828098254),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 2.0534873203680393),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 0.74566981111565923),
+   };
+   static const T Q_2_4[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 53, 1.0),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 2.8822787662376169),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 4.1681660554090917),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 2.7853527819234466),
+      BOOST_MATH_BIG_CONSTANT(T, 53, 0.74967671848044792),
+      BOOST_MATH_BIG_CONSTANT(T, 53, -0.00057069112416246805),
+   };
+   // Maximum Deviation Found:                     6.896e-018
+   // Expected Error Term :                       -6.895e-018
+   // Maximum Relative Change in Control Points :  8.497e-004
+   static const T P_4_inf[] = {
+      static_cast<T>(0.68947581948701249e-17L),
+      static_cast<T>(0.49999999999998975L),
+      static_cast<T>(1.0177274392923795L),
+      static_cast<T>(2.498208511343429L),
+      static_cast<T>(2.1921221359427595L),
+      static_cast<T>(1.5897035272532764L),
+      static_cast<T>(0.40154388356961734L),
+   };
+   static const T Q_4_inf[] = {
+      static_cast<T>(1.0L),
+      static_cast<T>(1.7021215452463932L),
+      static_cast<T>(4.4290431747556469L),
+      static_cast<T>(2.9745631894384922L),
+      static_cast<T>(2.3013614809773616L),
+      static_cast<T>(0.28360399799075752L),
+      static_cast<T>(0.022892987908906897L),
+   };
+
+   if(x <= 2)
+   {
+      return (offset + boost::math::tools::evaluate_polynomial(P_1_2, x) / tools::evaluate_polynomial(Q_1_2, x)) / (x * x);
+   }
+   else if(x <= 4)
+   {
+      T y = 1 / x;
+      return (1 + tools::evaluate_polynomial(P_2_4, y) / tools::evaluate_polynomial(Q_2_4, y)) / x;
+   }
+   T y = 1 / x;
+   return (1 + tools::evaluate_polynomial(P_4_inf, y) / tools::evaluate_polynomial(Q_4_inf, y)) / x;
+}
+   
+template <class T, class Policy>
+T trigamma_prec(T x, const boost::integral_constant<int, 64>*, const Policy&)
+{
+   // Max error in interpolated form: 1.178e-020
+   static const T offset_1_2 = BOOST_MATH_BIG_CONSTANT(T, 64, 2.109325408935546875);
+   static const T P_1_2[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, -1.10932535608960258341),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -4.18793841543017129052),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -4.63865531898487734531),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.919832884430500908047),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 1.68074038333180423012),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 1.21172611429185622377),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.259635673503366427284),
+   };
+   static const T Q_1_2[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 3.77521119359546982995),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 5.664338024578956321),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 4.25995134879278028361),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 1.62956638448940402182),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.259635512844691089868),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.629642219810618032207e-8),
+   };
+   // Max error in interpolated form: 3.912e-020
+   static const T P_2_8[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.387540035162952880976e-11),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.500000000276430504),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 3.21926880986360957306),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 10.2550347708483445775),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 18.9002075150709144043),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 21.0357215832399705625),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 13.4346512182925923978),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 3.98656291026448279118),
+   };
+   static const T Q_2_8[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 6.10520430478613667724),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 18.475001060603645512),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 31.7087534567758405638),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 31.908814523890465398),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 17.4175479039227084798),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 3.98749106958394941276),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.000115917322224411128566),
+   };
+   // Maximum Deviation Found:                     2.635e-020
+   // Expected Error Term :                        2.635e-020
+   // Maximum Relative Change in Control Points :  1.791e-003
+   static const T P_8_inf[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.263527875092466899848e-19),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.500000000000000058145),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.0730121433777364138677),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 1.94505878379957149534),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.0517092358874932620529),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 1.07995383547483921121),
+   };
+   static const T Q_8_inf[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.187309046577818095504),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 3.95255391645238842975),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -1.14743283327078949087),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 2.52989799376344914499),
+      BOOST_MATH_BIG_CONSTANT(T, 64, -0.627414303172402506396),
+      BOOST_MATH_BIG_CONSTANT(T, 64, 0.141554248216425512536),
+   };
+
+   if(x <= 2)
+   {
+      return (offset_1_2 + boost::math::tools::evaluate_polynomial(P_1_2, x) / tools::evaluate_polynomial(Q_1_2, x)) / (x * x);
+   }
+   else if(x <= 8)
+   {
+      T y = 1 / x;
+      return (1 + tools::evaluate_polynomial(P_2_8, y) / tools::evaluate_polynomial(Q_2_8, y)) / x;
+   }
+   T y = 1 / x;
+   return (1 + tools::evaluate_polynomial(P_8_inf, y) / tools::evaluate_polynomial(Q_8_inf, y)) / x;
+}
+
+template <class T, class Policy>
+T trigamma_prec(T x, const boost::integral_constant<int, 113>*, const Policy&)
+{
+   // Max error in interpolated form: 1.916e-035
+
+   static const T P_1_2[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.999999999999999082554457936871832533),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -4.71237311120865266379041700054847734),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -7.94125711970499027763789342500817316),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -5.74657746697664735258222071695644535),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.404213349456398905981223965160595687),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 2.47877781178642876561595890095758896),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 2.07714151702455125992166949812126433),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.858877899162360138844032265418028567),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.20499222604410032375789018837922397),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.0272103140348194747360175268778415049),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.0015764849020876949848954081173520686),
+   };
+   static const T Q_1_2[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 4.71237311120863419878375031457715223),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 9.58619118655339853449127952145877467),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 11.0940067269829372437561421279054968),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 8.09075424749327792073276309969037885),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 3.87705890159891405185343806884451286),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 1.22758678701914477836330837816976782),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.249092040606385004109672077814668716),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.0295750413900655597027079600025569048),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.00157648490200498142247694709728858139),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.161264050344059471721062360645432809e-14),
+   };
+
+   // Max error in interpolated form: 8.958e-035
+   static const T P_2_4[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, -2.55843734739907925764326773972215085),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -12.2830208240542011967952466273455887),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -23.9195022162767993526575786066414403),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -24.9256431504823483094158828285470862),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -14.7979122765478779075108064826412285),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -4.46654453928610666393276765059122272),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.0191439033405649675717082465687845002),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.515412052554351265708917209749037352),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.195378348786064304378247325360320038),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.0334761282624174313035014426794245393),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.002373665205942206348500250056602687),
+   };
+   static const T Q_2_4[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 4.80098558454419907830670928248659245),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 9.99220727843170133895059300223445265),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 11.8896146167631330735386697123464976),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 8.96613256683809091593793565879092581),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 4.47254136149624110878909334574485751),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 1.48600982028196527372434773913633152),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.319570735766764237068541501137990078),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.0407358345787680953107374215319322066),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.00237366520593271641375755486420859837),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.239554887903526152679337256236302116e-15),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.294749244740618656265237072002026314e-17),
+   };
+
+   static const T y_offset_2_4 = BOOST_MATH_BIG_CONSTANT(T, 113, 3.558437347412109375);
+
+   // Max error in interpolated form: 4.319e-035
+   static const T P_4_8[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.166626112697021464248967707021688845e-16),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.499999999999997739552090249208808197),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 6.40270945019053817915772473771553187),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 41.3833374155000608013677627389343329),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 166.803341854562809335667241074035245),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 453.39964786925369319960722793414521),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 851.153712317697055375935433362983944),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 1097.70657567285059133109286478004458),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 938.431232478455316020076349367632922),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 487.268001604651932322080970189930074),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 119.953445242335730062471193124820659),
+   };
+   static const T Q_4_8[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 12.4720855670474488978638945855932398),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 78.6093129753298570701376952709727391),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 307.470246050318322489781182863190127),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 805.140686101151538537565264188630079),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 1439.12019760292146454787601409644413),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 1735.6105285756048831268586001383127),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 1348.32500712856328019355198611280536),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 607.225985860570846699704222144650563),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 119.952317857277045332558673164517227),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.000140165918355036060868680809129436084),
+   };
+
+   // Maximum Deviation Found:                     2.867e-035
+   // Expected Error Term :                        2.866e-035
+   // Maximum Relative Change in Control Points :  2.662e-004
+   static const T P_8_16[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.184828315274146610610872315609837439e-19),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.500000000000000004122475157735807738),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 3.02533865247313349284875558880415875),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 13.5995927517457371243039532492642734),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 35.3132224283087906757037999452941588),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 67.1639424550714159157603179911505619),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 83.5767733658513967581959839367419891),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 71.073491212235705900866411319363501),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 35.8621515614725564575893663483998663),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 8.72152231639983491987779743154333318),
+   };
+   static const T Q_8_16[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 5.71734397161293452310624822415866372),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 25.293404179620438179337103263274815),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 62.2619767967468199111077640625328469),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 113.955048909238993473389714972250235),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 130.807138328938966981862203944329408),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 102.423146902337654110717764213057753),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 44.0424772805245202514468199602123565),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 8.89898032477904072082994913461386099),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -0.0296627336872039988632793863671456398),
+   };
+   // Maximum Deviation Found:                     1.079e-035
+   // Expected Error Term :                       -1.079e-035
+   // Maximum Relative Change in Control Points :  7.884e-003
+   static const T P_16_inf[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.0),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.500000000000000000000000000000087317),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.345625669885456215194494735902663968),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 9.62895499360842232127552650044647769),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 3.5936085382439026269301003761320812),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 49.459599118438883265036646019410669),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 7.77519237321893917784735690560496607),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 74.4536074488178075948642351179304121),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 2.75209340397069050436806159297952699),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 23.9292359711471667884504840186561598),
+   };
+   static const T Q_16_inf[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.357918006437579097055656138920742037),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 19.1386039850709849435325005484512944),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 0.874349081464143606016221431763364517),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 98.6516097434855572678195488061432509),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -16.1051972833382893468655223662534306),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 154.316860216253720989145047141653727),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -40.2026880424378986053105969312264534),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 60.1679136674264778074736441126810223),
+      BOOST_MATH_BIG_CONSTANT(T, 113, -13.3414844622256422644504472438320114),
+      BOOST_MATH_BIG_CONSTANT(T, 113, 2.53795636200649908779512969030363442),
+   };
+
+   if(x <= 2)
+   {
+      return (2 + boost::math::tools::evaluate_polynomial(P_1_2, x) / tools::evaluate_polynomial(Q_1_2, x)) / (x * x);
+   }
+   else if(x <= 4)
+   {
+      return (y_offset_2_4 + boost::math::tools::evaluate_polynomial(P_2_4, x) / tools::evaluate_polynomial(Q_2_4, x)) / (x * x);
+   }
+   else if(x <= 8)
+   {
+      T y = 1 / x;
+      return (1 + tools::evaluate_polynomial(P_4_8, y) / tools::evaluate_polynomial(Q_4_8, y)) / x;
+   }
+   else if(x <= 16)
+   {
+      T y = 1 / x;
+      return (1 + tools::evaluate_polynomial(P_8_16, y) / tools::evaluate_polynomial(Q_8_16, y)) / x;
+   }
+   T y = 1 / x;
+   return (1 + tools::evaluate_polynomial(P_16_inf, y) / tools::evaluate_polynomial(Q_16_inf, y)) / x;
+}
+
+template <class T, class Tag, class Policy>
+T trigamma_imp(T x, const Tag* t, const Policy& pol)
+{
+   //
+   // This handles reflection of negative arguments, and all our
+   // error handling, then forwards to the T-specific approximation.
+   //
+   BOOST_MATH_STD_USING // ADL of std functions.
+
+   T result = 0;
+   //
+   // Check for negative arguments and use reflection:
+   //
+   if(x <= 0)
+   {
+      // Reflect:
+      T z = 1 - x;
+      // Argument reduction for tan:
+      if(floor(x) == x)
+      {
+         return policies::raise_pole_error<T>("boost::math::trigamma<%1%>(%1%)", 0, (1-x), pol);
+      }
+      T s = fabs(x) < fabs(z) ? boost::math::sin_pi(x, pol) : boost::math::sin_pi(z, pol);
+      return -trigamma_imp(z, t, pol) + boost::math::pow<2>(constants::pi<T>()) / (s * s);
+   }
+   if(x < 1)
+   {
+      result = 1 / (x * x);
+      x += 1;
+   }
+   return result + trigamma_prec(x, t, pol);
+}
+
+template <class T, class Policy>
+T trigamma_imp(T x, const boost::integral_constant<int, 0>*, const Policy& pol)
+{
+   return polygamma_imp(1, x, pol);
+}
+//
+// Initializer: ensure all our constants are initialized prior to the first call of main:
+//
+template <class T, class Policy>
+struct trigamma_initializer
+{
+   struct init
+   {
+      init()
+      {
+         typedef typename policies::precision<T, Policy>::type precision_type;
+         do_init(boost::integral_constant<bool, precision_type::value && (precision_type::value <= 113)>());
+      }
+      void do_init(const boost::true_type&)
+      {
+         boost::math::trigamma(T(2.5), Policy());
+      }
+      void do_init(const boost::false_type&){}
+      void force_instantiate()const{}
+   };
+   static const init initializer;
+   static void force_instantiate()
+   {
+      initializer.force_instantiate();
+   }
+};
+
+template <class T, class Policy>
+const typename trigamma_initializer<T, Policy>::init trigamma_initializer<T, Policy>::initializer;
+
+} // namespace detail
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type 
+   trigamma(T x, const Policy&)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   typedef typename policies::precision<T, Policy>::type precision_type;
+   typedef boost::integral_constant<int,
+      precision_type::value <= 0 ? 0 :
+      precision_type::value <= 53 ? 53 :
+      precision_type::value <= 64 ? 64 :
+      precision_type::value <= 113 ? 113 : 0
+   > tag_type;
+   typedef typename policies::normalise<
+      Policy,
+      policies::promote_float<false>,
+      policies::promote_double<false>,
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+
+   // Force initialization of constants:
+   detail::trigamma_initializer<value_type, forwarding_policy>::force_instantiate();
+
+   return policies::checked_narrowing_cast<result_type, Policy>(detail::trigamma_imp(
+      static_cast<value_type>(x),
+      static_cast<const tag_type*>(0), forwarding_policy()), "boost::math::trigamma<%1%>(%1%)");
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type 
+   trigamma(T x)
+{
+   return trigamma(x, policies::policy<>());
+}
+
+} // namespace math
+} // namespace boost
+#endif
+
diff --git a/ThirdParty/boost/math/special_functions/trunc.hpp b/ThirdParty/boost/math/special_functions/trunc.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d4d322991d52ae9fb02f0d530a784e7ad122c828
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/trunc.hpp
@@ -0,0 +1,162 @@
+//  Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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_TRUNC_HPP
+#define BOOST_MATH_TRUNC_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/tools/config.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
+#include <boost/type_traits/is_constructible.hpp>
+#include <boost/core/enable_if.hpp>
+
+namespace boost{ namespace math{ namespace detail{
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type trunc(const T& v, const Policy& pol, const boost::false_type&)
+{
+   BOOST_MATH_STD_USING
+   typedef typename tools::promote_args<T>::type result_type;
+   if(!(boost::math::isfinite)(v))
+      return policies::raise_rounding_error("boost::math::trunc<%1%>(%1%)", 0, static_cast<result_type>(v), static_cast<result_type>(v), pol);
+   return (v >= 0) ? static_cast<result_type>(floor(v)) : static_cast<result_type>(ceil(v));
+}
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type trunc(const T& v, const Policy&, const boost::true_type&)
+{
+   return v;
+}
+
+}
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type trunc(const T& v, const Policy& pol)
+{
+   return detail::trunc(v, pol, boost::integral_constant<bool, detail::is_integer_for_rounding<T>::value>());
+}
+template <class T>
+inline typename tools::promote_args<T>::type trunc(const T& v)
+{
+   return trunc(v, policies::policy<>());
+}
+//
+// The following functions will not compile unless T has an
+// implicit conversion to the integer types.  For user-defined
+// number types this will likely not be the case.  In that case
+// these functions should either be specialized for the UDT in
+// question, or else overloads should be placed in the same
+// namespace as the UDT: these will then be found via argument
+// dependent lookup.  See our concept archetypes for examples.
+//
+template <class T, class Policy>
+inline int itrunc(const T& v, const Policy& pol)
+{
+   BOOST_MATH_STD_USING
+   typedef typename tools::promote_args<T>::type result_type;
+   result_type r = boost::math::trunc(v, pol);
+   if((r > (std::numeric_limits<int>::max)()) || (r < (std::numeric_limits<int>::min)()))
+      return static_cast<int>(policies::raise_rounding_error("boost::math::itrunc<%1%>(%1%)", 0, static_cast<result_type>(v), 0, pol));
+   return static_cast<int>(r);
+}
+template <class T>
+inline int itrunc(const T& v)
+{
+   return itrunc(v, policies::policy<>());
+}
+
+template <class T, class Policy>
+inline long ltrunc(const T& v, const Policy& pol)
+{
+   BOOST_MATH_STD_USING
+   typedef typename tools::promote_args<T>::type result_type;
+   result_type r = boost::math::trunc(v, pol);
+   if((r > (std::numeric_limits<long>::max)()) || (r < (std::numeric_limits<long>::min)()))
+      return static_cast<long>(policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", 0, static_cast<result_type>(v), 0L, pol));
+   return static_cast<long>(r);
+}
+template <class T>
+inline long ltrunc(const T& v)
+{
+   return ltrunc(v, policies::policy<>());
+}
+
+#ifdef BOOST_HAS_LONG_LONG
+
+template <class T, class Policy>
+inline boost::long_long_type lltrunc(const T& v, const Policy& pol)
+{
+   BOOST_MATH_STD_USING
+   typedef typename tools::promote_args<T>::type result_type;
+   result_type r = boost::math::trunc(v, pol);
+   if((r > (std::numeric_limits<boost::long_long_type>::max)()) || (r < (std::numeric_limits<boost::long_long_type>::min)()))
+      return static_cast<boost::long_long_type>(policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", 0, v, static_cast<boost::long_long_type>(0), pol));
+   return static_cast<boost::long_long_type>(r);
+}
+template <class T>
+inline boost::long_long_type lltrunc(const T& v)
+{
+   return lltrunc(v, policies::policy<>());
+}
+
+#endif
+
+template <class T, class Policy>
+inline typename boost::enable_if_c<boost::is_constructible<int, T>::value, int>::type
+   iconvert(const T& v, const Policy&) 
+{
+   return static_cast<int>(v);
+}
+
+template <class T, class Policy>
+inline typename boost::disable_if_c<boost::is_constructible<int, T>::value, int>::type
+   iconvert(const T& v, const Policy& pol) 
+{
+   using boost::math::itrunc;
+   return itrunc(v, pol);
+}
+
+template <class T, class Policy>
+inline typename boost::enable_if_c<boost::is_constructible<long, T>::value, long>::type
+   lconvert(const T& v, const Policy&) 
+{
+   return static_cast<long>(v);
+}
+
+template <class T, class Policy>
+inline typename boost::disable_if_c<boost::is_constructible<long, T>::value, long>::type
+   lconvert(const T& v, const Policy& pol) 
+{
+   using boost::math::ltrunc;
+   return ltrunc(v, pol);
+}
+
+#ifdef BOOST_HAS_LONG_LONG
+
+template <class T, class Policy>
+inline typename boost::enable_if_c<boost::is_constructible<boost::long_long_type, T>::value, boost::long_long_type>::type
+   llconvertert(const T& v, const Policy&) 
+{
+   return static_cast<boost::long_long_type>(v);
+}
+
+template <class T, class Policy>
+inline typename boost::disable_if_c<boost::is_constructible<boost::long_long_type, T>::value, boost::long_long_type>::type
+   llconvertert(const T& v, const Policy& pol) 
+{
+   using boost::math::lltrunc;
+   return lltrunc(v, pol);
+}
+
+#endif
+
+}} // namespaces
+
+#endif // BOOST_MATH_TRUNC_HPP
diff --git a/ThirdParty/boost/math/special_functions/zeta.hpp b/ThirdParty/boost/math/special_functions/zeta.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2b700ac46f96538e23c2b6c8ecfbaa3ad6d6eb1c
--- /dev/null
+++ b/ThirdParty/boost/math/special_functions/zeta.hpp
@@ -0,0 +1,1098 @@
+//  Copyright John Maddock 2007, 2014.
+//  Use, modification and distribution are subject to 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_ZETA_HPP
+#define BOOST_MATH_ZETA_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/special_functions/math_fwd.hpp>
+#include <boost/math/tools/precision.hpp>
+#include <boost/math/tools/series.hpp>
+#include <boost/math/tools/big_constant.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/special_functions/gamma.hpp>
+#include <boost/math/special_functions/factorials.hpp>
+#include <boost/math/special_functions/sin_pi.hpp>
+
+#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128)
+//
+// This is the only way we can avoid
+// warning: non-standard suffix on floating constant [-Wpedantic]
+// when building with -Wall -pedantic.  Neither __extension__
+// nor #pragma diagnostic ignored work :(
+//
+#pragma GCC system_header
+#endif
+
+namespace boost{ namespace math{ namespace detail{
+
+#if 0
+//
+// This code is commented out because we have a better more rapidly converging series
+// now.  Retained for future reference and in case the new code causes any issues down the line....
+//
+
+template <class T, class Policy>
+struct zeta_series_cache_size
+{
+   //
+   // Work how large to make our cache size when evaluating the series 
+   // evaluation:  normally this is just large enough for the series
+   // to have converged, but for arbitrary precision types we need a 
+   // really large cache to achieve reasonable precision in a reasonable 
+   // time.  This is important when constructing rational approximations
+   // to zeta for example.
+   //
+   typedef typename boost::math::policies::precision<T,Policy>::type precision_type;
+   typedef typename mpl::if_<
+      mpl::less_equal<precision_type, boost::integral_constant<int, 0> >,
+      boost::integral_constant<int, 5000>,
+      typename mpl::if_<
+         mpl::less_equal<precision_type, boost::integral_constant<int, 64> >,
+         boost::integral_constant<int, 70>,
+         typename mpl::if_<
+            mpl::less_equal<precision_type, boost::integral_constant<int, 113> >,
+            boost::integral_constant<int, 100>,
+            boost::integral_constant<int, 5000>
+         >::type
+      >::type
+   >::type type;
+};
+
+template <class T, class Policy>
+T zeta_series_imp(T s, T sc, const Policy&)
+{
+   //
+   // Series evaluation from:
+   // Havil, J. Gamma: Exploring Euler's Constant. 
+   // Princeton, NJ: Princeton University Press, 2003.
+   //
+   // See also http://mathworld.wolfram.com/RiemannZetaFunction.html
+   //
+   BOOST_MATH_STD_USING
+   T sum = 0;
+   T mult = 0.5;
+   T change;
+   typedef typename zeta_series_cache_size<T,Policy>::type cache_size;
+   T powers[cache_size::value] = { 0, };
+   unsigned n = 0;
+   do{
+      T binom = -static_cast<T>(n);
+      T nested_sum = 1;
+      if(n < sizeof(powers) / sizeof(powers[0]))
+         powers[n] = pow(static_cast<T>(n + 1), -s);
+      for(unsigned k = 1; k <= n; ++k)
+      {
+         T p;
+         if(k < sizeof(powers) / sizeof(powers[0]))
+         {
+            p = powers[k];
+            //p = pow(k + 1, -s);
+         }
+         else
+            p = pow(static_cast<T>(k + 1), -s);
+         nested_sum += binom * p;
+        binom *= (k - static_cast<T>(n)) / (k + 1);
+      }
+      change = mult * nested_sum;
+      sum += change;
+      mult /= 2;
+      ++n;
+   }while(fabs(change / sum) > tools::epsilon<T>());
+
+   return sum * 1 / -boost::math::powm1(T(2), sc);
+}
+
+//
+// Classical p-series:
+//
+template <class T>
+struct zeta_series2
+{
+   typedef T result_type;
+   zeta_series2(T _s) : s(-_s), k(1){}
+   T operator()()
+   {
+      BOOST_MATH_STD_USING
+      return pow(static_cast<T>(k++), s);
+   }
+private:
+   T s;
+   unsigned k;
+};
+
+template <class T, class Policy>
+inline T zeta_series2_imp(T s, const Policy& pol)
+{
+   boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();;
+   zeta_series2<T> f(s);
+   T result = tools::sum_series(
+      f, 
+      policies::get_epsilon<T, Policy>(),
+      max_iter);
+   policies::check_series_iterations<T>("boost::math::zeta_series2<%1%>(%1%)", max_iter, pol);
+   return result;
+}
+#endif
+
+template <class T, class Policy>
+T zeta_polynomial_series(T s, T sc, Policy const &)
+{
+   //
+   // This is algorithm 3 from:
+   // 
+   // "An Efficient Algorithm for the Riemann Zeta Function", P. Borwein, 
+   // Canadian Mathematical Society, Conference Proceedings.
+   // See: http://www.cecm.sfu.ca/personal/pborwein/PAPERS/P155.pdf
+   //
+   BOOST_MATH_STD_USING
+   int n = itrunc(T(log(boost::math::tools::epsilon<T>()) / -2));
+   T sum = 0;
+   T two_n = ldexp(T(1), n);
+   int ej_sign = 1;
+   for(int j = 0; j < n; ++j)
+   {
+      sum += ej_sign * -two_n / pow(T(j + 1), s);
+      ej_sign = -ej_sign; 
+   }
+   T ej_sum = 1;
+   T ej_term = 1;
+   for(int j = n; j <= 2 * n - 1; ++j)
+   {
+      sum += ej_sign * (ej_sum - two_n) / pow(T(j + 1), s);
+      ej_sign = -ej_sign;
+      ej_term *= 2 * n - j;
+      ej_term /= j - n + 1;
+      ej_sum += ej_term;
+   }
+   return -sum / (two_n * (-powm1(T(2), sc)));
+}
+
+template <class T, class Policy>
+T zeta_imp_prec(T s, T sc, const Policy& pol, const boost::integral_constant<int, 0>&)
+{
+   BOOST_MATH_STD_USING
+   T result;
+   if(s >= policies::digits<T, Policy>())
+      return 1;
+   result = zeta_polynomial_series(s, sc, pol); 
+#if 0
+   // Old code archived for future reference:
+
+   //
+   // Only use power series if it will converge in 100 
+   // iterations or less: the more iterations it consumes
+   // the slower convergence becomes so we have to be very 
+   // careful in it's usage.
+   //
+   if (s > -log(tools::epsilon<T>()) / 4.5)
+      result = detail::zeta_series2_imp(s, pol);
+   else
+      result = detail::zeta_series_imp(s, sc, pol);
+#endif
+   return result;
+}
+
+template <class T, class Policy>
+inline T zeta_imp_prec(T s, T sc, const Policy&, const boost::integral_constant<int, 53>&)
+{
+   BOOST_MATH_STD_USING
+   T result;
+   if(s < 1)
+   {
+      // Rational Approximation
+      // Maximum Deviation Found:                     2.020e-18
+      // Expected Error Term:                         -2.020e-18
+      // Max error found at double precision:         3.994987e-17
+      static const T P[6] = {    
+         static_cast<T>(0.24339294433593750202L),
+         static_cast<T>(-0.49092470516353571651L),
+         static_cast<T>(0.0557616214776046784287L),
+         static_cast<T>(-0.00320912498879085894856L),
+         static_cast<T>(0.000451534528645796438704L),
+         static_cast<T>(-0.933241270357061460782e-5L),
+        };
+      static const T Q[6] = {    
+         static_cast<T>(1L),
+         static_cast<T>(-0.279960334310344432495L),
+         static_cast<T>(0.0419676223309986037706L),
+         static_cast<T>(-0.00413421406552171059003L),
+         static_cast<T>(0.00024978985622317935355L),
+         static_cast<T>(-0.101855788418564031874e-4L),
+      };
+      result = tools::evaluate_polynomial(P, sc) / tools::evaluate_polynomial(Q, sc);
+      result -= 1.2433929443359375F;
+      result += (sc);
+      result /= (sc);
+   }
+   else if(s <= 2)
+   {
+      // Maximum Deviation Found:        9.007e-20
+      // Expected Error Term:            9.007e-20
+      static const T P[6] = {    
+         static_cast<T>(0.577215664901532860516L),
+         static_cast<T>(0.243210646940107164097L),
+         static_cast<T>(0.0417364673988216497593L),
+         static_cast<T>(0.00390252087072843288378L),
+         static_cast<T>(0.000249606367151877175456L),
+         static_cast<T>(0.110108440976732897969e-4L),
+      };
+      static const T Q[6] = {    
+         static_cast<T>(1.0),
+         static_cast<T>(0.295201277126631761737L),
+         static_cast<T>(0.043460910607305495864L),
+         static_cast<T>(0.00434930582085826330659L),
+         static_cast<T>(0.000255784226140488490982L),
+         static_cast<T>(0.10991819782396112081e-4L),
+      };
+      result = tools::evaluate_polynomial(P, T(-sc)) / tools::evaluate_polynomial(Q, T(-sc));
+      result += 1 / (-sc);
+   }
+   else if(s <= 4)
+   {
+      // Maximum Deviation Found:          5.946e-22
+      // Expected Error Term:              -5.946e-22
+      static const float Y = 0.6986598968505859375;
+      static const T P[6] = {    
+         static_cast<T>(-0.0537258300023595030676L),
+         static_cast<T>(0.0445163473292365591906L),
+         static_cast<T>(0.0128677673534519952905L),
+         static_cast<T>(0.00097541770457391752726L),
+         static_cast<T>(0.769875101573654070925e-4L),
+         static_cast<T>(0.328032510000383084155e-5L),
+      };
+      static const T Q[7] = {    
+         1.0f,
+         static_cast<T>(0.33383194553034051422L),
+         static_cast<T>(0.0487798431291407621462L),
+         static_cast<T>(0.00479039708573558490716L),
+         static_cast<T>(0.000270776703956336357707L),
+         static_cast<T>(0.106951867532057341359e-4L),
+         static_cast<T>(0.236276623974978646399e-7L),
+      };
+      result = tools::evaluate_polynomial(P, T(s - 2)) / tools::evaluate_polynomial(Q, T(s - 2));
+      result += Y + 1 / (-sc);
+   }
+   else if(s <= 7)
+   {
+      // Maximum Deviation Found:                     2.955e-17
+      // Expected Error Term:                         2.955e-17
+      // Max error found at double precision:         2.009135e-16
+
+      static const T P[6] = {    
+         static_cast<T>(-2.49710190602259410021L),
+         static_cast<T>(-2.60013301809475665334L),
+         static_cast<T>(-0.939260435377109939261L),
+         static_cast<T>(-0.138448617995741530935L),
+         static_cast<T>(-0.00701721240549802377623L),
+         static_cast<T>(-0.229257310594893932383e-4L),
+      };
+      static const T Q[9] = {    
+         1.0f,
+         static_cast<T>(0.706039025937745133628L),
+         static_cast<T>(0.15739599649558626358L),
+         static_cast<T>(0.0106117950976845084417L),
+         static_cast<T>(-0.36910273311764618902e-4L),
+         static_cast<T>(0.493409563927590008943e-5L),
+         static_cast<T>(-0.234055487025287216506e-6L),
+         static_cast<T>(0.718833729365459760664e-8L),
+         static_cast<T>(-0.1129200113474947419e-9L),
+      };
+      result = tools::evaluate_polynomial(P, T(s - 4)) / tools::evaluate_polynomial(Q, T(s - 4));
+      result = 1 + exp(result);
+   }
+   else if(s < 15)
+   {
+      // Maximum Deviation Found:                     7.117e-16
+      // Expected Error Term:                         7.117e-16
+      // Max error found at double precision:         9.387771e-16
+      static const T P[7] = {    
+         static_cast<T>(-4.78558028495135619286L),
+         static_cast<T>(-1.89197364881972536382L),
+         static_cast<T>(-0.211407134874412820099L),
+         static_cast<T>(-0.000189204758260076688518L),
+         static_cast<T>(0.00115140923889178742086L),
+         static_cast<T>(0.639949204213164496988e-4L),
+         static_cast<T>(0.139348932445324888343e-5L),
+        };
+      static const T Q[9] = {    
+         1.0f,
+         static_cast<T>(0.244345337378188557777L),
+         static_cast<T>(0.00873370754492288653669L),
+         static_cast<T>(-0.00117592765334434471562L),
+         static_cast<T>(-0.743743682899933180415e-4L),
+         static_cast<T>(-0.21750464515767984778e-5L),
+         static_cast<T>(0.471001264003076486547e-8L),
+         static_cast<T>(-0.833378440625385520576e-10L),
+         static_cast<T>(0.699841545204845636531e-12L),
+        };
+      result = tools::evaluate_polynomial(P, T(s - 7)) / tools::evaluate_polynomial(Q, T(s - 7));
+      result = 1 + exp(result);
+   }
+   else if(s < 36)
+   {
+      // Max error in interpolated form:             1.668e-17
+      // Max error found at long double precision:   1.669714e-17
+      static const T P[8] = {    
+         static_cast<T>(-10.3948950573308896825L),
+         static_cast<T>(-2.85827219671106697179L),
+         static_cast<T>(-0.347728266539245787271L),
+         static_cast<T>(-0.0251156064655346341766L),
+         static_cast<T>(-0.00119459173416968685689L),
+         static_cast<T>(-0.382529323507967522614e-4L),
+         static_cast<T>(-0.785523633796723466968e-6L),
+         static_cast<T>(-0.821465709095465524192e-8L),
+      };
+      static const T Q[10] = {    
+         1.0f,
+         static_cast<T>(0.208196333572671890965L),
+         static_cast<T>(0.0195687657317205033485L),
+         static_cast<T>(0.00111079638102485921877L),
+         static_cast<T>(0.408507746266039256231e-4L),
+         static_cast<T>(0.955561123065693483991e-6L),
+         static_cast<T>(0.118507153474022900583e-7L),
+         static_cast<T>(0.222609483627352615142e-14L),
+      };
+      result = tools::evaluate_polynomial(P, T(s - 15)) / tools::evaluate_polynomial(Q, T(s - 15));
+      result = 1 + exp(result);
+   }
+   else if(s < 56)
+   {
+      result = 1 + pow(T(2), -s);
+   }
+   else
+   {
+      result = 1;
+   }
+   return result;
+}
+
+template <class T, class Policy>
+T zeta_imp_prec(T s, T sc, const Policy&, const boost::integral_constant<int, 64>&)
+{
+   BOOST_MATH_STD_USING
+   T result;
+   if(s < 1)
+   {
+      // Rational Approximation
+      // Maximum Deviation Found:                     3.099e-20
+      // Expected Error Term:                         3.099e-20
+      // Max error found at long double precision:    5.890498e-20
+      static const T P[6] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.243392944335937499969),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.496837806864865688082),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.0680008039723709987107),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.00511620413006619942112),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.000455369899250053003335),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.279496685273033761927e-4),
+        };
+      static const T Q[7] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.30425480068225790522),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.050052748580371598736),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.00519355671064700627862),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.000360623385771198350257),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.159600883054550987633e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.339770279812410586032e-6),
+      };
+      result = tools::evaluate_polynomial(P, sc) / tools::evaluate_polynomial(Q, sc);
+      result -= 1.2433929443359375F;
+      result += (sc);
+      result /= (sc);
+   }
+   else if(s <= 2)
+   {
+      // Maximum Deviation Found:                     1.059e-21
+      // Expected Error Term:                         1.059e-21
+      // Max error found at long double precision:    1.626303e-19
+
+      static const T P[6] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.577215664901532860605),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.222537368917162139445),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.0356286324033215682729),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.00304465292366350081446),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.000178102511649069421904),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.700867470265983665042e-5),
+      };
+      static const T Q[7] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.259385759149531030085),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.0373974962106091316854),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.00332735159183332820617),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.000188690420706998606469),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.635994377921861930071e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.226583954978371199405e-7),
+      };
+      result = tools::evaluate_polynomial(P, T(-sc)) / tools::evaluate_polynomial(Q, T(-sc));
+      result += 1 / (-sc);
+   }
+   else if(s <= 4)
+   {
+      // Maximum Deviation Found:          5.946e-22
+      // Expected Error Term:              -5.946e-22
+      static const float Y = 0.6986598968505859375;
+      static const T P[7] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.053725830002359501027),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.0470551187571475844778),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.0101339410415759517471),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.00100240326666092854528),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.685027119098122814867e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.390972820219765942117e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.540319769113543934483e-7),
+      };
+      static const T Q[8] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.286577739726542730421),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.0447355811517733225843),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.00430125107610252363302),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.000284956969089786662045),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.116188101609848411329e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.278090318191657278204e-6),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.19683620233222028478e-8),
+      };
+      result = tools::evaluate_polynomial(P, T(s - 2)) / tools::evaluate_polynomial(Q, T(s - 2));
+      result += Y + 1 / (-sc);
+   }
+   else if(s <= 7)
+   {
+      // Max error found at long double precision: 8.132216e-19
+      static const T P[8] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 64, -2.49710190602259407065),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -3.36664913245960625334),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -1.77180020623777595452),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.464717885249654313933),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.0643694921293579472583),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.00464265386202805715487),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.000165556579779704340166),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.252884970740994069582e-5),
+      };
+      static const T Q[9] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 1.01300131390690459085),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.387898115758643503827),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.0695071490045701135188),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.00586908595251442839291),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.000217752974064612188616),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.397626583349419011731e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.927884739284359700764e-8),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.119810501805618894381e-9),
+      };
+      result = tools::evaluate_polynomial(P, T(s - 4)) / tools::evaluate_polynomial(Q, T(s - 4));
+      result = 1 + exp(result);
+   }
+   else if(s < 15)
+   {
+      // Max error in interpolated form:              1.133e-18
+      // Max error found at long double precision:    2.183198e-18
+      static const T P[9] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 64, -4.78558028495135548083),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -3.23873322238609358947),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.892338582881021799922),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.131326296217965913809),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.0115651591773783712996),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.000657728968362695775205),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.252051328129449973047e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.626503445372641798925e-6),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.815696314790853893484e-8),
+        };
+      static const T Q[9] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.525765665400123515036),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.10852641753657122787),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.0115669945375362045249),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.000732896513858274091966),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.30683952282420248448e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.819649214609633126119e-6),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.117957556472335968146e-7),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.193432300973017671137e-12),
+        };
+      result = tools::evaluate_polynomial(P, T(s - 7)) / tools::evaluate_polynomial(Q, T(s - 7));
+      result = 1 + exp(result);
+   }
+   else if(s < 42)
+   {
+      // Max error in interpolated form:             1.668e-17
+      // Max error found at long double precision:   1.669714e-17
+      static const T P[9] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 64, -10.3948950573308861781),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -2.82646012777913950108),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.342144362739570333665),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.0249285145498722647472),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.00122493108848097114118),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.423055371192592850196e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.1025215577185967488e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.165096762663509467061e-7),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.145392555873022044329e-9),
+      };
+      static const T Q[10] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 64, 1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.205135978585281988052),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.0192359357875879453602),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.00111496452029715514119),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.434928449016693986857e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.116911068726610725891e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.206704342290235237475e-7),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.209772836100827647474e-9),
+         BOOST_MATH_BIG_CONSTANT(T, 64, -0.939798249922234703384e-16),
+         BOOST_MATH_BIG_CONSTANT(T, 64, 0.264584017421245080294e-18),
+      };
+      result = tools::evaluate_polynomial(P, T(s - 15)) / tools::evaluate_polynomial(Q, T(s - 15));
+      result = 1 + exp(result);
+   }
+   else if(s < 63)
+   {
+      result = 1 + pow(T(2), -s);
+   }
+   else
+   {
+      result = 1;
+   }
+   return result;
+}
+
+template <class T, class Policy>
+T zeta_imp_prec(T s, T sc, const Policy&, const boost::integral_constant<int, 113>&)
+{
+   BOOST_MATH_STD_USING
+   T result;
+   if(s < 1)
+   {
+      // Rational Approximation
+      // Maximum Deviation Found:                     9.493e-37
+      // Expected Error Term:                         9.492e-37
+      // Max error found at long double precision:    7.281332e-31
+
+      static const T P[10] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 113, -1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.0353008629988648122808504280990313668),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.0107795651204927743049369868548706909),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.000523961870530500751114866884685172975),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.661805838304910731947595897966487515e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.658932670403818558510656304189164638e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.103437265642266106533814021041010453e-6),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.116818787212666457105375746642927737e-7),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.660690993901506912123512551294239036e-9),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.113103113698388531428914333768142527e-10),
+        };
+      static const T Q[11] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.387483472099602327112637481818565459),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.0802265315091063135271497708694776875),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.0110727276164171919280036408995078164),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.00112552716946286252000434849173787243),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.874554160748626916455655180296834352e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.530097847491828379568636739662278322e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.248461553590496154705565904497247452e-6),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.881834921354014787309644951507523899e-8),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.217062446168217797598596496310953025e-9),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.315823200002384492377987848307151168e-11),
+      };
+      result = tools::evaluate_polynomial(P, sc) / tools::evaluate_polynomial(Q, sc);
+      result += (sc);
+      result /= (sc);
+   }
+   else if(s <= 2)
+   {
+      // Maximum Deviation Found:                     1.616e-37
+      // Expected Error Term:                         -1.615e-37
+
+      static const T P[10] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.577215664901532860606512090082402431),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.255597968739771510415479842335906308),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.0494056503552807274142218876983542205),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.00551372778611700965268920983472292325),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.00043667616723970574871427830895192731),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.268562259154821957743669387915239528e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.109249633923016310141743084480436612e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.273895554345300227466534378753023924e-7),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.583103205551702720149237384027795038e-9),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.835774625259919268768735944711219256e-11),
+      };
+      static const T Q[11] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.316661751179735502065583176348292881),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.0540401806533507064453851182728635272),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.00598621274107420237785899476374043797),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.000474907812321704156213038740142079615),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.272125421722314389581695715835862418e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.112649552156479800925522445229212933e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.301838975502992622733000078063330461e-7),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.422960728687211282539769943184270106e-9),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.377105263588822468076813329270698909e-11),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.581926559304525152432462127383600681e-13),
+      };
+      result = tools::evaluate_polynomial(P, T(-sc)) / tools::evaluate_polynomial(Q, T(-sc));
+      result += 1 / (-sc);
+   }
+   else if(s <= 4)
+   {
+      // Maximum Deviation Found:                     1.891e-36
+      // Expected Error Term:                         -1.891e-36
+      // Max error found: 2.171527e-35
+
+      static const float Y = 0.6986598968505859375;
+      static const T P[11] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.0537258300023595010275848333539748089),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.0429086930802630159457448174466342553),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.0136148228754303412510213395034056857),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.00190231601036042925183751238033763915),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.000186880390916311438818302549192456581),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.145347370745893262394287982691323657e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.805843276446813106414036600485884885e-6),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.340818159286739137503297172091882574e-7),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.115762357488748996526167305116837246e-8),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.231904754577648077579913403645767214e-10),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.340169592866058506675897646629036044e-12),
+      };
+      static const T Q[12] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.363755247765087100018556983050520554),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.0696581979014242539385695131258321598),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.00882208914484611029571547753782014817),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.000815405623261946661762236085660996718),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.571366167062457197282642344940445452e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.309278269271853502353954062051797838e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.12822982083479010834070516053794262e-6),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.397876357325018976733953479182110033e-8),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.8484432107648683277598472295289279e-10),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.105677416606909614301995218444080615e-11),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.547223964564003701979951154093005354e-15),
+      };
+      result = tools::evaluate_polynomial(P, T(s - 2)) / tools::evaluate_polynomial(Q, T(s - 2));
+      result += Y + 1 / (-sc);
+   }
+   else if(s <= 6)
+   {
+      // Max error in interpolated form:             1.510e-37
+      // Max error found at long double precision:   2.769266e-34
+
+      static const T Y = 3.28348541259765625F;
+
+      static const T P[13] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.786383506575062179339611614117697622),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.495766593395271370974685959652073976),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.409116737851754766422360889037532228),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.57340744006238263817895456842655987),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.280479899797421910694892949057963111),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.0753148409447590257157585696212649869),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.0122934003684672788499099362823748632),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.00126148398446193639247961370266962927),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.828465038179772939844657040917364896e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.361008916706050977143208468690645684e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.109879825497910544424797771195928112e-6),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.214539416789686920918063075528797059e-8),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.15090220092460596872172844424267351e-10),
+      };
+      static const T Q[14] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 1.69490865837142338462982225731926485),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 1.22697696630994080733321401255942464),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.495409420862526540074366618006341533),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.122368084916843823462872905024259633),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.0191412993625268971656513890888208623),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.00191401538628980617753082598351559642),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.000123318142456272424148930280876444459),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.531945488232526067889835342277595709e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.161843184071894368337068779669116236e-6),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.305796079600152506743828859577462778e-8),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.233582592298450202680170811044408894e-10),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.275363878344548055574209713637734269e-13),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.221564186807357535475441900517843892e-15),
+      };
+      result = tools::evaluate_polynomial(P, T(s - 4)) / tools::evaluate_polynomial(Q, T(s - 4));
+      result -= Y;
+      result = 1 + exp(result);
+   }
+   else if(s < 10)
+   {
+      // Max error in interpolated form:             1.999e-34
+      // Max error found at long double precision:   2.156186e-33
+
+      static const T P[13] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 113, -4.0545627381873738086704293881227365),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -4.70088348734699134347906176097717782),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -2.36921550900925512951976617607678789),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.684322583796369508367726293719322866),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.126026534540165129870721937592996324),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.015636903921778316147260572008619549),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.00135442294754728549644376325814460807),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.842793965853572134365031384646117061e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.385602133791111663372015460784978351e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.130458500394692067189883214401478539e-6),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.315861074947230418778143153383660035e-8),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.500334720512030826996373077844707164e-10),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.420204769185233365849253969097184005e-12),
+        };
+      static const T Q[14] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.97663511666410096104783358493318814),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.40878780231201806504987368939673249),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.0963890666609396058945084107597727252),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.0142207619090854604824116070866614505),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.00139010220902667918476773423995750877),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.940669540194694997889636696089994734e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.458220848507517004399292480807026602e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.16345521617741789012782420625435495e-6),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.414007452533083304371566316901024114e-8),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.68701473543366328016953742622661377e-10),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.603461891080716585087883971886075863e-12),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.294670713571839023181857795866134957e-16),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.147003914536437243143096875069813451e-18),
+        };
+      result = tools::evaluate_polynomial(P, T(s - 6)) / tools::evaluate_polynomial(Q, T(s - 6));
+      result = 1 + exp(result);
+   }
+   else if(s < 17)
+   {
+      // Max error in interpolated form:             1.641e-32
+      // Max error found at long double precision:   1.696121e-32
+      static const T P[13] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 113, -6.91319491921722925920883787894829678),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -3.65491257639481960248690596951049048),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.813557553449954526442644544105257881),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.0994317301685870959473658713841138083),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.00726896610245676520248617014211734906),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.000317253318715075854811266230916762929),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.66851422826636750855184211580127133e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.879464154730985406003332577806849971e-7),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.113838903158254250631678791998294628e-7),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.379184410304927316385211327537817583e-9),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.612992858643904887150527613446403867e-11),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.347873737198164757035457841688594788e-13),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.289187187441625868404494665572279364e-15),
+        };
+      static const T Q[14] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.427310044448071818775721584949868806),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.074602514873055756201435421385243062),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.00688651562174480772901425121653945942),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.000360174847635115036351323894321880445),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.973556847713307543918865405758248777e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.853455848314516117964634714780874197e-8),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.118203513654855112421673192194622826e-7),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.462521662511754117095006543363328159e-9),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.834212591919475633107355719369463143e-11),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.5354594751002702935740220218582929e-13),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.406451690742991192964889603000756203e-15),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.887948682401000153828241615760146728e-19),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.34980761098820347103967203948619072e-21),
+        };
+      result = tools::evaluate_polynomial(P, T(s - 10)) / tools::evaluate_polynomial(Q, T(s - 10));
+      result = 1 + exp(result);
+   }
+   else if(s < 30)
+   {
+      // Max error in interpolated form:             1.563e-31
+      // Max error found at long double precision:   1.562725e-31
+
+      static const T P[13] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 113, -11.7824798233959252791987402769438322),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -4.36131215284987731928174218354118102),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.732260980060982349410898496846972204),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.0744985185694913074484248803015717388),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.00517228281320594683022294996292250527),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.000260897206152101522569969046299309939),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.989553462123121764865178453128769948e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.286916799741891410827712096608826167e-6),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.637262477796046963617949532211619729e-8),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.106796831465628373325491288787760494e-9),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.129343095511091870860498356205376823e-11),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.102397936697965977221267881716672084e-13),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.402663128248642002351627980255756363e-16),
+      };
+      static const T Q[14] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.311288325355705609096155335186466508),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.0438318468940415543546769437752132748),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.00374396349183199548610264222242269536),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.000218707451200585197339671707189281302),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.927578767487930747532953583797351219e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.294145760625753561951137473484889639e-6),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.704618586690874460082739479535985395e-8),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.126333332872897336219649130062221257e-9),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.16317315713773503718315435769352765e-11),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.137846712823719515148344938160275695e-13),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.580975420554224366450994232723910583e-16),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.291354445847552426900293580511392459e-22),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.73614324724785855925025452085443636e-25),
+      };
+      result = tools::evaluate_polynomial(P, T(s - 17)) / tools::evaluate_polynomial(Q, T(s - 17));
+      result = 1 + exp(result);
+   }
+   else if(s < 74)
+   {
+      // Max error in interpolated form:             2.311e-27
+      // Max error found at long double precision:   2.297544e-27
+      static const T P[14] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 113, -20.7944102007844314586649688802236072),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -4.95759941987499442499908748130192187),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.563290752832461751889194629200298688),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.0406197001137935911912457120706122877),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.0020846534789473022216888863613422293),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.808095978462109173749395599401375667e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.244706022206249301640890603610060959e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.589477682919645930544382616501666572e-7),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.113699573675553496343617442433027672e-8),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.174767860183598149649901223128011828e-10),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.210051620306761367764549971980026474e-12),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.189187969537370950337212675466400599e-14),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.116313253429564048145641663778121898e-16),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.376708747782400769427057630528578187e-19),
+      };
+      static const T Q[16] = {    
+         BOOST_MATH_BIG_CONSTANT(T, 113, 1.0),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.205076752981410805177554569784219717),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.0202526722696670378999575738524540269),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.001278305290005994980069466658219057),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.576404779858501791742255670403304787e-4),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.196477049872253010859712483984252067e-5),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.521863830500876189501054079974475762e-7),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.109524209196868135198775445228552059e-8),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.181698713448644481083966260949267825e-10),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.234793316975091282090312036524695562e-12),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.227490441461460571047545264251399048e-14),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.151500292036937400913870642638520668e-16),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.543475775154780935815530649335936121e-19),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.241647013434111434636554455083309352e-28),
+         BOOST_MATH_BIG_CONSTANT(T, 113, -0.557103423021951053707162364713587374e-31),
+         BOOST_MATH_BIG_CONSTANT(T, 113, 0.618708773442584843384712258199645166e-34),
+      };
+      result = tools::evaluate_polynomial(P, T(s - 30)) / tools::evaluate_polynomial(Q, T(s - 30));
+      result = 1 + exp(result);
+   }
+   else if(s < 117)
+   {
+      result = 1 + pow(T(2), -s);
+   }
+   else
+   {
+      result = 1;
+   }
+   return result;
+}
+
+template <class T, class Policy>
+T zeta_imp_odd_integer(int s, const T&, const Policy&, const true_type&)
+{
+   static const T results[] = {
+      BOOST_MATH_BIG_CONSTANT(T, 113, 1.2020569031595942853997381615114500), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0369277551433699263313654864570342), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0083492773819228268397975498497968), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0020083928260822144178527692324121), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0004941886041194645587022825264699), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0001227133475784891467518365263574), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000305882363070204935517285106451), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000076371976378997622736002935630), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000019082127165539389256569577951), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000004769329867878064631167196044), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000001192199259653110730677887189), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000298035035146522801860637051), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000074507117898354294919810042), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000018626597235130490064039099), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000004656629065033784072989233), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000001164155017270051977592974), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000291038504449709968692943), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000072759598350574810145209), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000018189896503070659475848), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000004547473783042154026799), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000001136868407680227849349), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000284217097688930185546), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000071054273952108527129), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000017763568435791203275), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000004440892103143813364), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000001110223025141066134), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000277555756213612417), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000069388939045441537), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000017347234760475766), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000004336808690020650), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000001084202172494241), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000271050543122347), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000067762635780452), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000016940658945098), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000004235164736273), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000001058791184068), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000264697796017), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000066174449004), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000016543612251), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000004135903063), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000001033975766), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000258493941), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000064623485), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000016155871), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000004038968), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000001009742), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000252435), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000063109), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000015777), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000003944), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000986), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000247), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000062), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000015), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000004), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000001),
+   };
+   return s > 113 ? 1 : results[(s - 3) / 2];
+}
+
+template <class T, class Policy>
+T zeta_imp_odd_integer(int s, const T& sc, const Policy& pol, const false_type&)
+{
+   static BOOST_MATH_THREAD_LOCAL bool is_init = false;
+   static BOOST_MATH_THREAD_LOCAL T results[50] = {};
+   static BOOST_MATH_THREAD_LOCAL int digits = tools::digits<T>();
+   int current_digits = tools::digits<T>();
+   if(digits != current_digits)
+   {
+      // Oh my precision has changed...
+      is_init = false;
+   }
+   if(!is_init)
+   {
+      is_init = true;
+      digits = current_digits;
+      for(unsigned k = 0; k < sizeof(results) / sizeof(results[0]); ++k)
+      {
+         T arg = k * 2 + 3;
+         T c_arg = 1 - arg;
+         results[k] = zeta_polynomial_series(arg, c_arg, pol);
+      }
+   }
+   unsigned index = (s - 3) / 2;
+   return index >= sizeof(results) / sizeof(results[0]) ? zeta_polynomial_series(T(s), sc, pol): results[index];
+}
+
+template <class T, class Policy, class Tag>
+T zeta_imp(T s, T sc, const Policy& pol, const Tag& tag)
+{
+   BOOST_MATH_STD_USING
+   static const char* function = "boost::math::zeta<%1%>";
+   if(sc == 0)
+      return policies::raise_pole_error<T>(
+         function, 
+         "Evaluation of zeta function at pole %1%", 
+         s, pol);
+   T result;
+   //
+   // Trivial case:
+   //
+   if(s > policies::digits<T, Policy>())
+      return 1;
+   //
+   // Start by seeing if we have a simple closed form:
+   //
+   if(floor(s) == s)
+   {
+#ifndef BOOST_NO_EXCEPTIONS
+      // Without exceptions we expect itrunc to return INT_MAX on overflow
+      // and we fall through anyway.
+      try
+      {
+#endif
+         int v = itrunc(s);
+         if(v == s)
+         {
+            if(v < 0)
+            {
+               if(((-v) & 1) == 0)
+                  return 0;
+               int n = (-v + 1) / 2;
+               if(n <= (int)boost::math::max_bernoulli_b2n<T>::value)
+                  return T((-v & 1) ? -1 : 1) * boost::math::unchecked_bernoulli_b2n<T>(n) / (1 - v);
+            }
+            else if((v & 1) == 0)
+            {
+               if(((v / 2) <= (int)boost::math::max_bernoulli_b2n<T>::value) && (v <= (int)boost::math::max_factorial<T>::value))
+                  return T(((v / 2 - 1) & 1) ? -1 : 1) * ldexp(T(1), v - 1) * pow(constants::pi<T, Policy>(), v) *
+                     boost::math::unchecked_bernoulli_b2n<T>(v / 2) / boost::math::unchecked_factorial<T>(v);
+               return T(((v / 2 - 1) & 1) ? -1 : 1) * ldexp(T(1), v - 1) * pow(constants::pi<T, Policy>(), v) *
+                  boost::math::bernoulli_b2n<T>(v / 2) / boost::math::factorial<T>(v);
+            }
+            else
+               return zeta_imp_odd_integer(v, sc, pol, boost::integral_constant<bool, (Tag::value <= 113) && Tag::value>());
+         }
+#ifndef BOOST_NO_EXCEPTIONS
+      }
+      catch(const boost::math::rounding_error&){} // Just fall through, s is too large to round
+      catch(const std::overflow_error&){}
+#endif
+   }
+
+   if(fabs(s) < tools::root_epsilon<T>())
+   {
+      result = -0.5f - constants::log_root_two_pi<T, Policy>() * s;
+   }
+   else if(s < 0)
+   {
+      std::swap(s, sc);
+      if(floor(sc/2) == sc/2)
+         result = 0;
+      else
+      {
+         if(s > max_factorial<T>::value)
+         {
+            T mult = boost::math::sin_pi(0.5f * sc, pol) * 2 * zeta_imp(s, sc, pol, tag);
+            result = boost::math::lgamma(s, pol);
+            result -= s * log(2 * constants::pi<T>());
+            if(result > tools::log_max_value<T>())
+               return sign(mult) * policies::raise_overflow_error<T>(function, 0, pol);
+            result = exp(result);
+            if(tools::max_value<T>() / fabs(mult) < result)
+               return boost::math::sign(mult) * policies::raise_overflow_error<T>(function, 0, pol);
+            result *= mult;
+         }
+         else
+         {
+            result = boost::math::sin_pi(0.5f * sc, pol)
+               * 2 * pow(2 * constants::pi<T>(), -s) 
+               * boost::math::tgamma(s, pol) 
+               * zeta_imp(s, sc, pol, tag);
+         }
+      }
+   }
+   else
+   {
+      result = zeta_imp_prec(s, sc, pol, tag);
+   }
+   return result;
+}
+
+template <class T, class Policy, class tag>
+struct zeta_initializer
+{
+   struct init
+   {
+      init()
+      {
+         do_init(tag());
+      }
+      static void do_init(const boost::integral_constant<int, 0>&){ boost::math::zeta(static_cast<T>(5), Policy()); }
+      static void do_init(const boost::integral_constant<int, 53>&){ boost::math::zeta(static_cast<T>(5), Policy()); }
+      static void do_init(const boost::integral_constant<int, 64>&)
+      {
+         boost::math::zeta(static_cast<T>(0.5), Policy());
+         boost::math::zeta(static_cast<T>(1.5), Policy());
+         boost::math::zeta(static_cast<T>(3.5), Policy());
+         boost::math::zeta(static_cast<T>(6.5), Policy());
+         boost::math::zeta(static_cast<T>(14.5), Policy());
+         boost::math::zeta(static_cast<T>(40.5), Policy());
+
+         boost::math::zeta(static_cast<T>(5), Policy());
+      }
+      static void do_init(const boost::integral_constant<int, 113>&)
+      {
+         boost::math::zeta(static_cast<T>(0.5), Policy());
+         boost::math::zeta(static_cast<T>(1.5), Policy());
+         boost::math::zeta(static_cast<T>(3.5), Policy());
+         boost::math::zeta(static_cast<T>(5.5), Policy());
+         boost::math::zeta(static_cast<T>(9.5), Policy());
+         boost::math::zeta(static_cast<T>(16.5), Policy());
+         boost::math::zeta(static_cast<T>(25.5), Policy());
+         boost::math::zeta(static_cast<T>(70.5), Policy());
+
+         boost::math::zeta(static_cast<T>(5), Policy());
+      }
+      void force_instantiate()const{}
+   };
+   static const init initializer;
+   static void force_instantiate()
+   {
+      initializer.force_instantiate();
+   }
+};
+
+template <class T, class Policy, class tag>
+const typename zeta_initializer<T, Policy, tag>::init zeta_initializer<T, Policy, tag>::initializer;
+
+} // detail
+
+template <class T, class Policy>
+inline typename tools::promote_args<T>::type zeta(T s, const Policy&)
+{
+   typedef typename tools::promote_args<T>::type result_type;
+   typedef typename policies::evaluation<result_type, Policy>::type value_type;
+   typedef typename policies::precision<result_type, Policy>::type precision_type;
+   typedef typename policies::normalise<
+      Policy, 
+      policies::promote_float<false>, 
+      policies::promote_double<false>, 
+      policies::discrete_quantile<>,
+      policies::assert_undefined<> >::type forwarding_policy;
+   typedef boost::integral_constant<int,
+      precision_type::value <= 0 ? 0 :
+      precision_type::value <= 53 ? 53 :
+      precision_type::value <= 64 ? 64 :
+      precision_type::value <= 113 ? 113 : 0
+   > tag_type;
+
+   detail::zeta_initializer<value_type, forwarding_policy, tag_type>::force_instantiate();
+
+   return policies::checked_narrowing_cast<result_type, forwarding_policy>(detail::zeta_imp(
+      static_cast<value_type>(s),
+      static_cast<value_type>(1 - static_cast<value_type>(s)),
+      forwarding_policy(),
+      tag_type()), "boost::math::zeta<%1%>(%1%)");
+}
+
+template <class T>
+inline typename tools::promote_args<T>::type zeta(T s)
+{
+   return zeta(s, policies::policy<>());
+}
+
+}} // namespaces
+
+#endif // BOOST_MATH_ZETA_HPP
+
+
+
diff --git a/ThirdParty/boost/math/tools/atomic.hpp b/ThirdParty/boost/math/tools/atomic.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d2b8022c69c91e61ad68183dc0d0e3030daa62b2
--- /dev/null
+++ b/ThirdParty/boost/math/tools/atomic.hpp
@@ -0,0 +1,94 @@
+///////////////////////////////////////////////////////////////////////////////
+//  Copyright 2017 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_ATOMIC_DETAIL_HPP
+#define BOOST_MATH_ATOMIC_DETAIL_HPP
+
+#include <boost/config.hpp>
+#include <boost/math/tools/cxx03_warn.hpp>
+
+#ifdef BOOST_HAS_THREADS
+
+#ifndef BOOST_NO_CXX11_HDR_ATOMIC
+#  include <atomic>
+#  define BOOST_MATH_ATOMIC_NS std
+namespace boost {
+   namespace math {
+      namespace detail {
+#if ATOMIC_INT_LOCK_FREE == 2
+         typedef std::atomic<int> atomic_counter_type;
+         typedef std::atomic<unsigned> atomic_unsigned_type;
+         typedef int atomic_integer_type;
+         typedef unsigned atomic_unsigned_integer_type;
+#elif ATOMIC_SHORT_LOCK_FREE == 2
+         typedef std::atomic<short> atomic_counter_type;
+         typedef std::atomic<unsigned short> atomic_unsigned_type;
+         typedef short atomic_integer_type;
+         typedef unsigned short atomic_unsigned_type;
+#elif ATOMIC_LONG_LOCK_FREE == 2
+         typedef std::atomic<long> atomic_unsigned_integer_type;
+         typedef std::atomic<unsigned long> atomic_unsigned_type;
+         typedef unsigned long atomic_unsigned_type;
+         typedef long atomic_integer_type;
+#elif ATOMIC_LLONG_LOCK_FREE == 2
+         typedef std::atomic<long long> atomic_unsigned_integer_type;
+         typedef std::atomic<unsigned long long> atomic_unsigned_type;
+         typedef long long atomic_integer_type;
+         typedef unsigned long long atomic_unsigned_integer_type;
+#else
+#  define BOOST_MATH_NO_ATOMIC_INT
+#endif
+      }
+   }}
+#else // BOOST_NO_CXX11_HDR_ATOMIC
+//
+// We need Boost.Atomic, but on any platform that supports auto-linking we do
+// not need to link against a separate library:
+//
+#define BOOST_ATOMIC_NO_LIB
+#include <boost/atomic.hpp>
+#  define BOOST_MATH_ATOMIC_NS boost
+
+namespace boost{ namespace math{ namespace detail{
+
+//
+// We need a type to use as an atomic counter:
+//
+#if BOOST_ATOMIC_INT_LOCK_FREE == 2
+typedef boost::atomic<int> atomic_counter_type;
+typedef boost::atomic<unsigned> atomic_unsigned_type;
+typedef int atomic_integer_type;
+typedef unsigned atomic_unsigned_integer_type;
+#elif BOOST_ATOMIC_SHORT_LOCK_FREE == 2
+typedef boost::atomic<short> atomic_counter_type;
+typedef boost::atomic<unsigned short> atomic_unsigned_type;
+typedef short atomic_integer_type;
+typedef unsigned short atomic_unsigned_integer_type;
+#elif BOOST_ATOMIC_LONG_LOCK_FREE == 2
+typedef boost::atomic<long> atomic_counter_type;
+typedef boost::atomic<unsigned long> atomic_unsigned_type;
+typedef long atomic_integer_type;
+typedef unsigned long atomic_unsigned_integer_type;
+#elif BOOST_ATOMIC_LLONG_LOCK_FREE == 2
+typedef boost::atomic<long long> atomic_counter_type;
+typedef boost::atomic<unsigned long long> atomic_unsigned_type;
+typedef long long atomic_integer_type;
+typedef unsigned long long atomic_unsigned_integer_type;
+#else
+#  define BOOST_MATH_NO_ATOMIC_INT
+#endif
+
+}}} // namespaces
+
+#endif  // BOOST_NO_CXX11_HDR_ATOMIC
+
+#else // BOOST_HAS_THREADS
+
+#  define BOOST_MATH_NO_ATOMIC_INT
+
+#endif // BOOST_HAS_THREADS
+
+#endif // BOOST_MATH_ATOMIC_DETAIL_HPP
diff --git a/ThirdParty/boost/math/tools/big_constant.hpp b/ThirdParty/boost/math/tools/big_constant.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..aad7ea133119bd68f8438bcdd739c4151d1c2e58
--- /dev/null
+++ b/ThirdParty/boost/math/tools/big_constant.hpp
@@ -0,0 +1,88 @@
+
+//  Copyright (c) 2011 John Maddock
+//  Use, modification and distribution are subject to 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_TOOLS_BIG_CONSTANT_HPP
+#define BOOST_MATH_TOOLS_BIG_CONSTANT_HPP
+
+#include <boost/math/tools/config.hpp>
+#ifndef BOOST_MATH_NO_LEXICAL_CAST
+#include <boost/lexical_cast.hpp>
+#endif
+#include <boost/type_traits/is_constructible.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/is_floating_point.hpp>
+
+namespace boost{ namespace math{ 
+
+namespace tools{
+
+template <class T>
+struct numeric_traits : public std::numeric_limits< T > {};
+
+#ifdef BOOST_MATH_USE_FLOAT128
+typedef __float128 largest_float;
+#define BOOST_MATH_LARGEST_FLOAT_C(x) x##Q
+template <>
+struct numeric_traits<__float128>
+{
+   static const int digits = 113;
+   static const int digits10 = 33;
+   static const int max_exponent = 16384;
+   static const bool is_specialized = true;
+};
+#else
+typedef long double largest_float;
+#define BOOST_MATH_LARGEST_FLOAT_C(x) x##L
+#endif
+
+template <class T>
+inline BOOST_CONSTEXPR_OR_CONST T make_big_value(largest_float v, const char*, boost::true_type const&, boost::false_type const&) BOOST_MATH_NOEXCEPT(T)
+{
+   return static_cast<T>(v);
+}
+template <class T>
+inline BOOST_CONSTEXPR_OR_CONST T make_big_value(largest_float v, const char*, boost::true_type const&, boost::true_type const&) BOOST_MATH_NOEXCEPT(T)
+{
+   return static_cast<T>(v);
+}
+#ifndef BOOST_MATH_NO_LEXICAL_CAST
+template <class T>
+inline T make_big_value(largest_float, const char* s, boost::false_type const&, boost::false_type const&)
+{
+   return boost::lexical_cast<T>(s);
+}
+#endif
+template <class T>
+inline BOOST_MATH_CONSTEXPR T make_big_value(largest_float, const char* s, boost::false_type const&, boost::true_type const&) BOOST_MATH_NOEXCEPT(T)
+{
+   return T(s);
+}
+
+//
+// For constants which might fit in a long double (if it's big enough):
+//
+#define BOOST_MATH_BIG_CONSTANT(T, D, x)\
+   boost::math::tools::make_big_value<T>(\
+      BOOST_MATH_LARGEST_FLOAT_C(x), \
+      BOOST_STRINGIZE(x), \
+      boost::integral_constant<bool, (boost::is_convertible<boost::math::tools::largest_float, T>::value) && \
+      ((D <= boost::math::tools::numeric_traits<boost::math::tools::largest_float>::digits) \
+          || boost::is_floating_point<T>::value \
+          || (boost::math::tools::numeric_traits<T>::is_specialized && \
+          (boost::math::tools::numeric_traits<T>::digits10 <= boost::math::tools::numeric_traits<boost::math::tools::largest_float>::digits10))) >(), \
+      boost::is_constructible<T, const char*>())
+//
+// For constants too huge for any conceivable long double (and which generate compiler errors if we try and declare them as such):
+//
+#define BOOST_MATH_HUGE_CONSTANT(T, D, x)\
+   boost::math::tools::make_big_value<T>(0.0L, BOOST_STRINGIZE(x), \
+   boost::integral_constant<bool, boost::is_floating_point<T>::value || (boost::math::tools::numeric_traits<T>::is_specialized && boost::math::tools::numeric_traits<T>::max_exponent <= boost::math::tools::numeric_traits<boost::math::tools::largest_float>::max_exponent && boost::math::tools::numeric_traits<T>::digits <= boost::math::tools::numeric_traits<boost::math::tools::largest_float>::digits)>(), \
+   boost::is_constructible<T, const char*>())
+
+}}} // namespaces
+
+#endif
+
diff --git a/ThirdParty/boost/math/tools/complex.hpp b/ThirdParty/boost/math/tools/complex.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..8bad37445c92dea2087ea0242cf415b57bdbe8bc
--- /dev/null
+++ b/ThirdParty/boost/math/tools/complex.hpp
@@ -0,0 +1,62 @@
+//  Copyright John Maddock 2018.
+//  Use, modification and distribution are subject to 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)
+
+//
+// Tools for operator on complex as well as scalar types.
+//
+
+#ifndef BOOST_MATH_TOOLS_COMPLEX_HPP
+#define BOOST_MATH_TOOLS_COMPLEX_HPP
+
+#include <boost/type_traits/is_complex.hpp>
+
+namespace boost {
+   namespace math {
+      namespace tools {
+
+         //
+         // Specialize this trait for user-defined complex types (ie Boost.Multiprecision):
+         //
+         template <class T>
+         struct is_complex_type : public boost::is_complex<T> {};
+         //
+         // Use this trait to typecast integer literals to something
+         // that will interoperate with T:
+         //
+         template <class T, bool = is_complex_type<T>::value>
+         struct integer_scalar_type
+         {
+            typedef int type;
+         };
+         template <class T>
+         struct integer_scalar_type<T, true>
+         {
+            typedef typename T::value_type type;
+         };
+         template <class T, bool = is_complex_type<T>::value>
+         struct unsigned_scalar_type
+         {
+            typedef unsigned type;
+         };
+         template <class T>
+         struct unsigned_scalar_type<T, true>
+         {
+            typedef typename T::value_type type;
+         };
+         template <class T, bool = is_complex_type<T>::value>
+         struct scalar_type
+         {
+            typedef T type;
+         };
+         template <class T>
+         struct scalar_type<T, true>
+         {
+            typedef typename T::value_type type;
+         };
+
+
+} } }
+
+#endif // BOOST_MATH_TOOLS_COMPLEX_HPP
diff --git a/ThirdParty/boost/math/tools/convert_from_string.hpp b/ThirdParty/boost/math/tools/convert_from_string.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4a206c44f0b15a2ab4f7c5a7bd90bbaf2055b6d6
--- /dev/null
+++ b/ThirdParty/boost/math/tools/convert_from_string.hpp
@@ -0,0 +1,51 @@
+//  Copyright John Maddock 2016.
+//  Use, modification and distribution are subject to 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_TOOLS_CONVERT_FROM_STRING_INCLUDED
+#define BOOST_MATH_TOOLS_CONVERT_FROM_STRING_INCLUDED
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/type_traits/is_constructible.hpp>
+#include <boost/type_traits/conditional.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace boost{ namespace math{ namespace tools{
+
+   template <class T>
+   struct convert_from_string_result
+   {
+      typedef typename boost::conditional<boost::is_constructible<T, const char*>::value, const char*, T>::type type;
+   };
+
+   template <class Real>
+   Real convert_from_string(const char* p, const boost::false_type&)
+   {
+#ifdef BOOST_MATH_NO_LEXICAL_CAST
+      // This function should not compile, we don't have the necessary functionality to support it:
+      BOOST_STATIC_ASSERT(sizeof(Real) == 0);
+#else
+      return boost::lexical_cast<Real>(p);
+#endif
+   }
+   template <class Real>
+   BOOST_CONSTEXPR const char* convert_from_string(const char* p, const boost::true_type&) BOOST_NOEXCEPT
+   {
+      return p;
+   }
+   template <class Real>
+   BOOST_CONSTEXPR typename convert_from_string_result<Real>::type convert_from_string(const char* p) BOOST_NOEXCEPT_IF((boost::is_constructible<Real, const char*>::value))
+   {
+      return convert_from_string<Real>(p, boost::is_constructible<Real, const char*>());
+   }
+
+} // namespace tools
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_TOOLS_CONVERT_FROM_STRING_INCLUDED
+
diff --git a/ThirdParty/boost/math/tools/cxx03_warn.hpp b/ThirdParty/boost/math/tools/cxx03_warn.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..dd36227bc0988e88b9530ef8f51ab97e158228ed
--- /dev/null
+++ b/ThirdParty/boost/math/tools/cxx03_warn.hpp
@@ -0,0 +1,106 @@
+//  Copyright (c) 2020 John Maddock
+//  Use, modification and distribution are subject to 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_TOOLS_CXX03_WARN_HPP
+#define BOOST_MATH_TOOLS_CXX03_WARN_HPP
+
+#include <boost/config/pragma_message.hpp>
+
+#if defined(BOOST_NO_CXX11_NOEXCEPT)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NOEXCEPT"
+#endif
+#if defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NOEXCEPT"
+#endif
+#if defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NOEXCEPT"
+#endif
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_RVALUE_REFERENCES"
+#endif
+#if defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_SFINAE_EXPR"
+#endif
+#if defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_AUTO_DECLARATIONS"
+#endif
+#if defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_LAMBDAS"
+#endif
+#if defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX"
+#endif
+#if defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_HDR_TUPLE"
+#endif
+#if defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_HDR_INITIALIZER_LIST"
+#endif
+#if defined(BOOST_NO_CXX11_HDR_CHRONO) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_HDR_CHRONO"
+#endif
+#if defined(BOOST_NO_CXX11_THREAD_LOCAL) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_THREAD_LOCAL"
+#endif
+#if defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_CONSTEXPR"
+#endif
+#if defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NULLPTR"
+#endif
+#if defined(BOOST_NO_CXX11_NUMERIC_LIMITS) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NUMERIC_LIMITS"
+#endif
+#if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_DECLTYPE"
+#endif
+#if defined(BOOST_NO_CXX11_HDR_ARRAY) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_HDR_ARRAY"
+#endif
+#if defined(BOOST_NO_CXX11_HDR_ATOMIC) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_HDR_ATOMIC"
+#endif
+#if defined(BOOST_NO_CXX11_ALLOCATOR) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_ALLOCATOR"
+#endif
+#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) && !defined(BOOST_MATH_SHOW_CXX03_WARNING)
+#  define BOOST_MATH_SHOW_CXX03_WARNING
+#  define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS"
+#endif
+
+#ifdef BOOST_MATH_SHOW_CXX03_WARNING
+//
+// 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_MATH_DISABLE_DEPRECATED_03_WARNING)
+BOOST_PRAGMA_MESSAGE("CAUTION: One or more C++11 features were found to be unavailable")
+BOOST_PRAGMA_MESSAGE("CAUTION: Compiling Boost.Math in pre-C++11 conformance modes is now deprecated and will be removed from March 2021.")
+BOOST_PRAGMA_MESSAGE("CAUTION: Define BOOST_MATH_DISABLE_DEPRECATED_03_WARNING to suppress this message.")
+BOOST_PRAGMA_MESSAGE("CAUTION: This message was generated due to the define: " BOOST_MATH_CXX03_WARN_REASON)
+#endif
+#endif
+
+#endif
diff --git a/ThirdParty/boost/math/tools/detail/is_const_iterable.hpp b/ThirdParty/boost/math/tools/detail/is_const_iterable.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7d04adb1fe112b440dd5046d0c89825eb877a4b3
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/is_const_iterable.hpp
@@ -0,0 +1,43 @@
+//  (C) Copyright John Maddock 2018.
+//  Use, modification and distribution are subject to 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_TOOLS_IS_CONST_ITERABLE_HPP
+#define BOOST_MATH_TOOLS_IS_CONST_ITERABLE_HPP
+
+#include <boost/config.hpp>
+#include <boost/math/tools/cxx03_warn.hpp>
+
+#if !defined(BOOST_NO_CXX14_VARIABLE_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_SFINAE_EXPR)
+
+#define BOOST_MATH_HAS_IS_CONST_ITERABLE
+
+#include <boost/type_traits/is_detected.hpp>
+#include <utility>
+
+namespace boost {
+   namespace math {
+      namespace tools {
+         namespace detail {
+
+            template<class T>
+            using begin_t = decltype(std::declval<const T&>().begin());
+            template<class T>
+            using end_t = decltype(std::declval<const T&>().end());
+            template<class T>
+            using const_iterator_t = typename T::const_iterator;
+
+            template <class T>
+            struct is_const_iterable
+               : public boost::integral_constant<bool,
+               boost::is_detected<begin_t, T>::value
+               && boost::is_detected<end_t, T>::value
+               && boost::is_detected<const_iterator_t, T>::value
+               > {};
+
+} } } }
+
+#endif
+
+#endif // BOOST_MATH_TOOLS_IS_CONST_ITERABLE_HPP
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_10.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_10.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..045a286b731a677323a885446c50b470e4d3b937
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_10.hpp
@@ -0,0 +1,84 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_10_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_10_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_11.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_11.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..20b5085d2e92e9f21c6207e95dfb8de89ba850aa
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_11.hpp
@@ -0,0 +1,90 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_11_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_11_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_12.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_12.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ee7649c48775f5805829a5aeb916a34223a9eff8
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_12.hpp
@@ -0,0 +1,96 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_12_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_12_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_13.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_13.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..fcbb3e6a7631bc4faf3ad0b17776a85f88bfcdbd
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_13.hpp
@@ -0,0 +1,102 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_13_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_13_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_14.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_14.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..0042882b4f493772d70f15bc645139bcb4946a90
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_14.hpp
@@ -0,0 +1,108 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_14_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_14_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_15.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_15.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..14fef4fbaa2e5c7e68703a9bc221182aae550ae2
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_15.hpp
@@ -0,0 +1,114 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_15_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_15_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_16.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_16.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b92cb4c0cf65dcab9e9b9855fec47e00a6c87984
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_16.hpp
@@ -0,0 +1,120 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_16_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_16_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_17.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_17.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..25aba5032488ea4c0e732af02405d822a7cbc773
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_17.hpp
@@ -0,0 +1,126 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_17_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_17_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_18.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_18.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d0deccc65f8a4a822168b38bc72a2ecc15dff3b5
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_18.hpp
@@ -0,0 +1,132 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_18_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_18_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_19.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_19.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d836273d5d98ac88364dc2ba5a692e681e6fd7e1
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_19.hpp
@@ -0,0 +1,138 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_19_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_19_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 19>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((((((((a[18] * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_2.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_2.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..66ca5fe1eac5573148190d903458ef12e39d2872
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_2.hpp
@@ -0,0 +1,36 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_2_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_2_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_20.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_20.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c8bbcdb3871e13e0efac626845f83e37d3d75d92
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_20.hpp
@@ -0,0 +1,144 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_20_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_20_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 19>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((((((((((((a[18] * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 20>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((((((((((((((a[19] * x + a[18]) * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_3.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_3.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..111866a751fb09141aee29d1778b57951a696d5a
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_3.hpp
@@ -0,0 +1,42 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_3_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_3_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_4.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_4.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1582171b2f7ff3fea5638662f3ad1413f832f2ca
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_4.hpp
@@ -0,0 +1,48 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_4_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_4_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_5.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_5.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..0d48d4434b74025b567e4142f5c410efa5849f13
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_5.hpp
@@ -0,0 +1,54 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_5_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_5_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_6.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_6.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4f148264ffed44a94cafa480393d97111594a08f
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_6.hpp
@@ -0,0 +1,60 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_6_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_6_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_7.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_7.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..47882985e8d4ec0e5eb18ccae93af0209ff4629f
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_7.hpp
@@ -0,0 +1,66 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_7_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_7_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_8.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_8.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..76729a57c414fd632dbb8bb44c748ba5eb5d980f
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_8.hpp
@@ -0,0 +1,72 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_8_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_8_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner1_9.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner1_9.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9669b71c00f17670d035fef9f22115bbcc141e1e
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner1_9.hpp
@@ -0,0 +1,78 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_9_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_9_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_10.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_10.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3d9ed88d284d8aecaf21d52f11acd1141a445cff
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_10.hpp
@@ -0,0 +1,90 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_10_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_10_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_11.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_11.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..24ee429051235115c87c99e662c710557fdc02ac
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_11.hpp
@@ -0,0 +1,97 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_11_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_11_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_12.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_12.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..731187f1bb6304466647fde9dc591d79e720a4d4
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_12.hpp
@@ -0,0 +1,104 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_12_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_12_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_13.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_13.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7528d2809fe8d1d2ab6f14c94e4b122580f908eb
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_13.hpp
@@ -0,0 +1,111 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_13_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_13_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_14.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_14.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..8f95bfe20570b1317dec819ad9dbf7a321d73256
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_14.hpp
@@ -0,0 +1,118 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_14_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_14_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_15.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_15.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5117926c5c435820e5ca25e7e71592e2726ef656
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_15.hpp
@@ -0,0 +1,125 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_15_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_15_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_16.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_16.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2d4e79ce6cdef11e198ec7a838f76802208925cf
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_16.hpp
@@ -0,0 +1,132 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_16_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_16_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_17.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_17.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1657aaf4156aedfc6131cd278edbd0a651046e95
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_17.hpp
@@ -0,0 +1,139 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_17_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_17_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_18.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_18.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..07c77a4ba109577a9192900a8d7530fdc35ca640
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_18.hpp
@@ -0,0 +1,146 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_18_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_18_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_19.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_19.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..441e867bda8f72a768133f5ae75cb40ba9e5e69b
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_19.hpp
@@ -0,0 +1,153 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_19_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_19_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 19>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_2.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_2.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..03b2820b5ddce5232df893f1b78566ad040e116b
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_2.hpp
@@ -0,0 +1,48 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_2_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_2_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_20.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_20.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7432b4708a9307eb4efbcc9cd32299cb45a607f3
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_20.hpp
@@ -0,0 +1,160 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_20_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_20_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 19>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 20>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((((((((a[19] * x2 + a[17]) * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_3.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_3.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c621ea8b2aae41696912e9baae71cb6f73440125
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_3.hpp
@@ -0,0 +1,48 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_3_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_3_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_4.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_4.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..733015ab06a72072d583eeabbced48916a757684
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_4.hpp
@@ -0,0 +1,48 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_4_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_4_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_5.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_5.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..bc43950951cec87935ea32fd457e56274967c90f
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_5.hpp
@@ -0,0 +1,55 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_5_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_5_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_6.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_6.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..fdbddc3f96dec1e7d21f20d4f604b406310473cf
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_6.hpp
@@ -0,0 +1,62 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_6_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_6_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_7.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_7.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..acc4c3b204d5208b99d9044ec778bd75a11e714f
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_7.hpp
@@ -0,0 +1,69 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_7_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_7_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_8.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_8.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1e0535947a292e5d7ca0e68784a6407adcf3ee55
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_8.hpp
@@ -0,0 +1,76 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_8_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_8_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner2_9.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner2_9.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3dc0075406c9d82b80627405c4c9fd5639f4559c
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner2_9.hpp
@@ -0,0 +1,83 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_9_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_9_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   return static_cast<V>((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_10.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_10.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b33c3181f153e888914e9cca283a4ffc46c63a2e
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_10.hpp
@@ -0,0 +1,156 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_10_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_10_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[4] * x2 + a[2]);
+   t[1] = static_cast<V>(a[3] * x2 + a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[5] * x2 + a[3];
+   t[1] = a[4] * x2 + a[2];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[6] * x2 + a[4]);
+   t[1] = static_cast<V>(a[5] * x2 + a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[7] * x2 + a[5];
+   t[1] = a[6] * x2 + a[4];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[8] * x2 + a[6]);
+   t[1] = static_cast<V>(a[7] * x2 + a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[9] * x2 + a[7];
+   t[1] = a[8] * x2 + a[6];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_11.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_11.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d28b0cd32b0fbff262e17d4b1594ec7d9374caa4
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_11.hpp
@@ -0,0 +1,181 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_11_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_11_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[4] * x2 + a[2]);
+   t[1] = static_cast<V>(a[3] * x2 + a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[5] * x2 + a[3];
+   t[1] = a[4] * x2 + a[2];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[6] * x2 + a[4]);
+   t[1] = static_cast<V>(a[5] * x2 + a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[7] * x2 + a[5];
+   t[1] = a[6] * x2 + a[4];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[8] * x2 + a[6]);
+   t[1] = static_cast<V>(a[7] * x2 + a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[9] * x2 + a[7];
+   t[1] = a[8] * x2 + a[6];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[10] * x2 + a[8]);
+   t[1] = static_cast<V>(a[9] * x2 + a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_12.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_12.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6f75578657569a4918c52256d38fe0bfc7350703
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_12.hpp
@@ -0,0 +1,208 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_12_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_12_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[4] * x2 + a[2]);
+   t[1] = static_cast<V>(a[3] * x2 + a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[5] * x2 + a[3];
+   t[1] = a[4] * x2 + a[2];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[6] * x2 + a[4]);
+   t[1] = static_cast<V>(a[5] * x2 + a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[7] * x2 + a[5];
+   t[1] = a[6] * x2 + a[4];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[8] * x2 + a[6]);
+   t[1] = static_cast<V>(a[7] * x2 + a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[9] * x2 + a[7];
+   t[1] = a[8] * x2 + a[6];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[10] * x2 + a[8]);
+   t[1] = static_cast<V>(a[9] * x2 + a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[11] * x2 + a[9];
+   t[1] = a[10] * x2 + a[8];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_13.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_13.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..def4b65c60f35682faa50b1c7c1679df0be837ba
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_13.hpp
@@ -0,0 +1,237 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_13_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_13_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[4] * x2 + a[2]);
+   t[1] = static_cast<V>(a[3] * x2 + a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[5] * x2 + a[3];
+   t[1] = a[4] * x2 + a[2];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[6] * x2 + a[4]);
+   t[1] = static_cast<V>(a[5] * x2 + a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[7] * x2 + a[5];
+   t[1] = a[6] * x2 + a[4];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[8] * x2 + a[6]);
+   t[1] = static_cast<V>(a[7] * x2 + a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[9] * x2 + a[7];
+   t[1] = a[8] * x2 + a[6];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[10] * x2 + a[8]);
+   t[1] = static_cast<V>(a[9] * x2 + a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[11] * x2 + a[9];
+   t[1] = a[10] * x2 + a[8];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[12] * x2 + a[10]);
+   t[1] = static_cast<V>(a[11] * x2 + a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_14.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_14.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e0cc7ea33b3cb8edeb868c9673ceb24b74214798
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_14.hpp
@@ -0,0 +1,268 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_14_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_14_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[4] * x2 + a[2]);
+   t[1] = static_cast<V>(a[3] * x2 + a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[5] * x2 + a[3];
+   t[1] = a[4] * x2 + a[2];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[6] * x2 + a[4]);
+   t[1] = static_cast<V>(a[5] * x2 + a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[7] * x2 + a[5];
+   t[1] = a[6] * x2 + a[4];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[8] * x2 + a[6]);
+   t[1] = static_cast<V>(a[7] * x2 + a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[9] * x2 + a[7];
+   t[1] = a[8] * x2 + a[6];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[10] * x2 + a[8]);
+   t[1] = static_cast<V>(a[9] * x2 + a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[11] * x2 + a[9];
+   t[1] = a[10] * x2 + a[8];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[12] * x2 + a[10]);
+   t[1] = static_cast<V>(a[11] * x2 + a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[13] * x2 + a[11];
+   t[1] = a[12] * x2 + a[10];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[9]);
+   t[1] += static_cast<V>(a[8]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_15.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_15.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9a16637ea988a32368c46f4c4609e1fa47a0c396
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_15.hpp
@@ -0,0 +1,301 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_15_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_15_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[4] * x2 + a[2]);
+   t[1] = static_cast<V>(a[3] * x2 + a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[5] * x2 + a[3];
+   t[1] = a[4] * x2 + a[2];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[6] * x2 + a[4]);
+   t[1] = static_cast<V>(a[5] * x2 + a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[7] * x2 + a[5];
+   t[1] = a[6] * x2 + a[4];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[8] * x2 + a[6]);
+   t[1] = static_cast<V>(a[7] * x2 + a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[9] * x2 + a[7];
+   t[1] = a[8] * x2 + a[6];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[10] * x2 + a[8]);
+   t[1] = static_cast<V>(a[9] * x2 + a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[11] * x2 + a[9];
+   t[1] = a[10] * x2 + a[8];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[12] * x2 + a[10]);
+   t[1] = static_cast<V>(a[11] * x2 + a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[13] * x2 + a[11];
+   t[1] = a[12] * x2 + a[10];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[9]);
+   t[1] += static_cast<V>(a[8]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[14] * x2 + a[12]);
+   t[1] = static_cast<V>(a[13] * x2 + a[11]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[10]);
+   t[1] += static_cast<V>(a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_16.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_16.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..28a9248c03f588709d16b2e39d3f3ca64cf170ab
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_16.hpp
@@ -0,0 +1,336 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_16_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_16_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[4] * x2 + a[2]);
+   t[1] = static_cast<V>(a[3] * x2 + a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[5] * x2 + a[3];
+   t[1] = a[4] * x2 + a[2];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[6] * x2 + a[4]);
+   t[1] = static_cast<V>(a[5] * x2 + a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[7] * x2 + a[5];
+   t[1] = a[6] * x2 + a[4];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[8] * x2 + a[6]);
+   t[1] = static_cast<V>(a[7] * x2 + a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[9] * x2 + a[7];
+   t[1] = a[8] * x2 + a[6];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[10] * x2 + a[8]);
+   t[1] = static_cast<V>(a[9] * x2 + a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[11] * x2 + a[9];
+   t[1] = a[10] * x2 + a[8];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[12] * x2 + a[10]);
+   t[1] = static_cast<V>(a[11] * x2 + a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[13] * x2 + a[11];
+   t[1] = a[12] * x2 + a[10];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[9]);
+   t[1] += static_cast<V>(a[8]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[14] * x2 + a[12]);
+   t[1] = static_cast<V>(a[13] * x2 + a[11]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[10]);
+   t[1] += static_cast<V>(a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[15] * x2 + a[13];
+   t[1] = a[14] * x2 + a[12];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[11]);
+   t[1] += static_cast<V>(a[10]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[9]);
+   t[1] += static_cast<V>(a[8]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_17.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_17.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..8c6d4108de1611f752d319f53b5905b6432b5fa3
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_17.hpp
@@ -0,0 +1,373 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_17_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_17_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[4] * x2 + a[2]);
+   t[1] = static_cast<V>(a[3] * x2 + a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[5] * x2 + a[3];
+   t[1] = a[4] * x2 + a[2];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[6] * x2 + a[4]);
+   t[1] = static_cast<V>(a[5] * x2 + a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[7] * x2 + a[5];
+   t[1] = a[6] * x2 + a[4];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[8] * x2 + a[6]);
+   t[1] = static_cast<V>(a[7] * x2 + a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[9] * x2 + a[7];
+   t[1] = a[8] * x2 + a[6];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[10] * x2 + a[8]);
+   t[1] = static_cast<V>(a[9] * x2 + a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[11] * x2 + a[9];
+   t[1] = a[10] * x2 + a[8];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[12] * x2 + a[10]);
+   t[1] = static_cast<V>(a[11] * x2 + a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[13] * x2 + a[11];
+   t[1] = a[12] * x2 + a[10];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[9]);
+   t[1] += static_cast<V>(a[8]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[14] * x2 + a[12]);
+   t[1] = static_cast<V>(a[13] * x2 + a[11]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[10]);
+   t[1] += static_cast<V>(a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[15] * x2 + a[13];
+   t[1] = a[14] * x2 + a[12];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[11]);
+   t[1] += static_cast<V>(a[10]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[9]);
+   t[1] += static_cast<V>(a[8]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[16] * x2 + a[14]);
+   t[1] = static_cast<V>(a[15] * x2 + a[13]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[12]);
+   t[1] += static_cast<V>(a[11]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[10]);
+   t[1] += static_cast<V>(a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_18.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_18.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2eccbac64b9a824f96d6535eae6ba6e10ef812d5
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_18.hpp
@@ -0,0 +1,412 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_18_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_18_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[4] * x2 + a[2]);
+   t[1] = static_cast<V>(a[3] * x2 + a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[5] * x2 + a[3];
+   t[1] = a[4] * x2 + a[2];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[6] * x2 + a[4]);
+   t[1] = static_cast<V>(a[5] * x2 + a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[7] * x2 + a[5];
+   t[1] = a[6] * x2 + a[4];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[8] * x2 + a[6]);
+   t[1] = static_cast<V>(a[7] * x2 + a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[9] * x2 + a[7];
+   t[1] = a[8] * x2 + a[6];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[10] * x2 + a[8]);
+   t[1] = static_cast<V>(a[9] * x2 + a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[11] * x2 + a[9];
+   t[1] = a[10] * x2 + a[8];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[12] * x2 + a[10]);
+   t[1] = static_cast<V>(a[11] * x2 + a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[13] * x2 + a[11];
+   t[1] = a[12] * x2 + a[10];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[9]);
+   t[1] += static_cast<V>(a[8]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[14] * x2 + a[12]);
+   t[1] = static_cast<V>(a[13] * x2 + a[11]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[10]);
+   t[1] += static_cast<V>(a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[15] * x2 + a[13];
+   t[1] = a[14] * x2 + a[12];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[11]);
+   t[1] += static_cast<V>(a[10]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[9]);
+   t[1] += static_cast<V>(a[8]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[16] * x2 + a[14]);
+   t[1] = static_cast<V>(a[15] * x2 + a[13]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[12]);
+   t[1] += static_cast<V>(a[11]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[10]);
+   t[1] += static_cast<V>(a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[17] * x2 + a[15];
+   t[1] = a[16] * x2 + a[14];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[13]);
+   t[1] += static_cast<V>(a[12]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[11]);
+   t[1] += static_cast<V>(a[10]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[9]);
+   t[1] += static_cast<V>(a[8]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_19.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_19.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..74ad91cb11f0899969009b5281487be4e3855815
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_19.hpp
@@ -0,0 +1,453 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_19_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_19_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[4] * x2 + a[2]);
+   t[1] = static_cast<V>(a[3] * x2 + a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[5] * x2 + a[3];
+   t[1] = a[4] * x2 + a[2];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[6] * x2 + a[4]);
+   t[1] = static_cast<V>(a[5] * x2 + a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[7] * x2 + a[5];
+   t[1] = a[6] * x2 + a[4];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[8] * x2 + a[6]);
+   t[1] = static_cast<V>(a[7] * x2 + a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[9] * x2 + a[7];
+   t[1] = a[8] * x2 + a[6];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[10] * x2 + a[8]);
+   t[1] = static_cast<V>(a[9] * x2 + a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[11] * x2 + a[9];
+   t[1] = a[10] * x2 + a[8];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[12] * x2 + a[10]);
+   t[1] = static_cast<V>(a[11] * x2 + a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[13] * x2 + a[11];
+   t[1] = a[12] * x2 + a[10];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[9]);
+   t[1] += static_cast<V>(a[8]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[14] * x2 + a[12]);
+   t[1] = static_cast<V>(a[13] * x2 + a[11]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[10]);
+   t[1] += static_cast<V>(a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[15] * x2 + a[13];
+   t[1] = a[14] * x2 + a[12];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[11]);
+   t[1] += static_cast<V>(a[10]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[9]);
+   t[1] += static_cast<V>(a[8]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[16] * x2 + a[14]);
+   t[1] = static_cast<V>(a[15] * x2 + a[13]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[12]);
+   t[1] += static_cast<V>(a[11]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[10]);
+   t[1] += static_cast<V>(a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[17] * x2 + a[15];
+   t[1] = a[16] * x2 + a[14];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[13]);
+   t[1] += static_cast<V>(a[12]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[11]);
+   t[1] += static_cast<V>(a[10]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[9]);
+   t[1] += static_cast<V>(a[8]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 19>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[18] * x2 + a[16]);
+   t[1] = static_cast<V>(a[17] * x2 + a[15]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[14]);
+   t[1] += static_cast<V>(a[13]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[12]);
+   t[1] += static_cast<V>(a[11]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[10]);
+   t[1] += static_cast<V>(a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_2.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_2.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ee2ac6e5a7460a5202d304f51ba3168cd6e57dd8
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_2.hpp
@@ -0,0 +1,48 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_2_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_2_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_20.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_20.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b683d9298649acae2ceb95ec5a012e58c249cb9e
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_20.hpp
@@ -0,0 +1,496 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_20_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_20_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[4] * x2 + a[2]);
+   t[1] = static_cast<V>(a[3] * x2 + a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[5] * x2 + a[3];
+   t[1] = a[4] * x2 + a[2];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[6] * x2 + a[4]);
+   t[1] = static_cast<V>(a[5] * x2 + a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[7] * x2 + a[5];
+   t[1] = a[6] * x2 + a[4];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[8] * x2 + a[6]);
+   t[1] = static_cast<V>(a[7] * x2 + a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[9] * x2 + a[7];
+   t[1] = a[8] * x2 + a[6];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[10] * x2 + a[8]);
+   t[1] = static_cast<V>(a[9] * x2 + a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[11] * x2 + a[9];
+   t[1] = a[10] * x2 + a[8];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[12] * x2 + a[10]);
+   t[1] = static_cast<V>(a[11] * x2 + a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[13] * x2 + a[11];
+   t[1] = a[12] * x2 + a[10];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[9]);
+   t[1] += static_cast<V>(a[8]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[14] * x2 + a[12]);
+   t[1] = static_cast<V>(a[13] * x2 + a[11]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[10]);
+   t[1] += static_cast<V>(a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[15] * x2 + a[13];
+   t[1] = a[14] * x2 + a[12];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[11]);
+   t[1] += static_cast<V>(a[10]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[9]);
+   t[1] += static_cast<V>(a[8]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[16] * x2 + a[14]);
+   t[1] = static_cast<V>(a[15] * x2 + a[13]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[12]);
+   t[1] += static_cast<V>(a[11]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[10]);
+   t[1] += static_cast<V>(a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[17] * x2 + a[15];
+   t[1] = a[16] * x2 + a[14];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[13]);
+   t[1] += static_cast<V>(a[12]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[11]);
+   t[1] += static_cast<V>(a[10]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[9]);
+   t[1] += static_cast<V>(a[8]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 19>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[18] * x2 + a[16]);
+   t[1] = static_cast<V>(a[17] * x2 + a[15]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[14]);
+   t[1] += static_cast<V>(a[13]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[12]);
+   t[1] += static_cast<V>(a[11]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[10]);
+   t[1] += static_cast<V>(a[9]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[8]);
+   t[1] += static_cast<V>(a[7]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[6]);
+   t[1] += static_cast<V>(a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 20>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[19] * x2 + a[17];
+   t[1] = a[18] * x2 + a[16];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[15]);
+   t[1] += static_cast<V>(a[14]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[13]);
+   t[1] += static_cast<V>(a[12]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[11]);
+   t[1] += static_cast<V>(a[10]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[9]);
+   t[1] += static_cast<V>(a[8]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[7]);
+   t[1] += static_cast<V>(a[6]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[5]);
+   t[1] += static_cast<V>(a[4]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_3.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_3.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9f8487d6659231363b5a2c7cbe99e89ed2bbfd45
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_3.hpp
@@ -0,0 +1,48 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_3_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_3_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_4.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_4.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..8c0ab196d4ac8161f239486c3ff801744ec747e3
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_4.hpp
@@ -0,0 +1,48 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_4_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_4_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_5.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_5.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5c1c7542e9aca17e62bd3308f0f0adccec618b17
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_5.hpp
@@ -0,0 +1,61 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_5_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_5_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[4] * x2 + a[2]);
+   t[1] = static_cast<V>(a[3] * x2 + a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_6.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_6.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..66f95109ee1586f85811b309aac8095327913d73
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_6.hpp
@@ -0,0 +1,76 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_6_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_6_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[4] * x2 + a[2]);
+   t[1] = static_cast<V>(a[3] * x2 + a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[5] * x2 + a[3];
+   t[1] = a[4] * x2 + a[2];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_7.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_7.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..8d15345c3d9388498cf4abd896fa09a1ef5a1516
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_7.hpp
@@ -0,0 +1,93 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_7_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_7_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[4] * x2 + a[2]);
+   t[1] = static_cast<V>(a[3] * x2 + a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[5] * x2 + a[3];
+   t[1] = a[4] * x2 + a[2];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[6] * x2 + a[4]);
+   t[1] = static_cast<V>(a[5] * x2 + a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_8.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_8.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..af65efff430bafb6a3b2f66a2229065d4466a5ab
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_8.hpp
@@ -0,0 +1,112 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_8_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_8_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[4] * x2 + a[2]);
+   t[1] = static_cast<V>(a[3] * x2 + a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[5] * x2 + a[3];
+   t[1] = a[4] * x2 + a[2];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[6] * x2 + a[4]);
+   t[1] = static_cast<V>(a[5] * x2 + a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[7] * x2 + a[5];
+   t[1] = a[6] * x2 + a[4];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/polynomial_horner3_9.hpp b/ThirdParty/boost/math/tools/detail/polynomial_horner3_9.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ac598da5b97105d15373316df25308a7c09ef7b3
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/polynomial_horner3_9.hpp
@@ -0,0 +1,133 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Unrolled polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_EVAL_9_HPP
+#define BOOST_MATH_TOOLS_POLY_EVAL_9_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[1] * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[2] * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[4] * x2 + a[2]);
+   t[1] = static_cast<V>(a[3] * x2 + a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[5] * x2 + a[3];
+   t[1] = a[4] * x2 + a[2];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[6] * x2 + a[4]);
+   t[1] = static_cast<V>(a[5] * x2 + a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = a[7] * x2 + a[5];
+   t[1] = a[6] * x2 + a[4];
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[3]);
+   t[1] += static_cast<V>(a[2]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[1]);
+   t[1] += static_cast<V>(a[0]);
+   t[0] *= x;
+   return t[0] + t[1];
+}
+
+template <class T, class V>
+inline V evaluate_polynomial_c_imp(const T* a, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   V x2 = x * x;
+   V t[2];
+   t[0] = static_cast<V>(a[8] * x2 + a[6]);
+   t[1] = static_cast<V>(a[7] * x2 + a[5]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[4]);
+   t[1] += static_cast<V>(a[3]);
+   t[0] *= x2;
+   t[1] *= x2;
+   t[0] += static_cast<V>(a[2]);
+   t[1] += static_cast<V>(a[1]);
+   t[0] *= x2;
+   t[0] += static_cast<V>(a[0]);
+   t[1] *= x;
+   return t[0] + t[1];
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_10.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_10.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..916551066ad45dddac14662c112f6878f067a5f7
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_10.hpp
@@ -0,0 +1,138 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_10_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_10_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_11.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_11.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..10aa93330b859d56816491fe17440880d3c67232
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_11.hpp
@@ -0,0 +1,150 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_11_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_11_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_12.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_12.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..058807980fd37f23fe6abf2e84fac3f3e451a595
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_12.hpp
@@ -0,0 +1,162 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_12_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_12_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_13.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_13.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9d3bdf981f759bdcbe7afedb0a651e1727e94aa6
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_13.hpp
@@ -0,0 +1,174 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_13_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_13_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_14.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_14.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d726b92ef3a369fc8195f94507703af562838cf7
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_14.hpp
@@ -0,0 +1,186 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_14_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_14_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_15.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_15.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..0a120ff003ff38574ea35730f861cc4c54928584
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_15.hpp
@@ -0,0 +1,198 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_15_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_15_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_16.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_16.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..0c93c224ede7d06a8ce501c2af0a16fcce6aa1ce
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_16.hpp
@@ -0,0 +1,210 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_16_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_16_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((b[15] * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) / (((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_17.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_17.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5c753d6c93b50851ad89753d845f147aea64b839
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_17.hpp
@@ -0,0 +1,222 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_17_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_17_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((b[15] * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) / (((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((b[16] * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) / ((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_18.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_18.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a9bd161477dff817619e5c2f877612258a517d6a
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_18.hpp
@@ -0,0 +1,234 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_18_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_18_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((b[15] * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) / (((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((b[16] * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) / ((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((((b[17] * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) / (((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_19.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_19.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..10d4b416dc8442cfa675dc921c66450556bda846
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_19.hpp
@@ -0,0 +1,246 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_19_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_19_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((b[15] * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) / (((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((b[16] * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) / ((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((((b[17] * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) / (((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 19>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((((((((a[18] * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((((b[18] * x + b[17]) * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) * z + a[18]) / ((((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17]) * z + b[18]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_2.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_2.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..70b7a9f44c26d8478a3d5813cc6f895c36c90674
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_2.hpp
@@ -0,0 +1,42 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_2_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_2_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_20.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_20.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..093a522c984dab8b353171e72cdabf302670a286
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_20.hpp
@@ -0,0 +1,258 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_20_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_20_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((b[15] * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) / (((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((b[16] * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) / ((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((((b[17] * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) / (((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 19>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((((((((((((a[18] * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((((b[18] * x + b[17]) * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) * z + a[18]) / ((((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17]) * z + b[18]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 20>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((((((((((((((a[19] * x + a[18]) * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((((((b[19] * x + b[18]) * x + b[17]) * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) * z + a[18]) * z + a[19]) / (((((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17]) * z + b[18]) * z + b[19]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_3.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_3.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4cb4e43b74a16da3fe6e866294c9c6b19ff5bb00
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_3.hpp
@@ -0,0 +1,54 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_3_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_3_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_4.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_4.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..bc9e5fe81903e62c11264571ed62078170556039
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_4.hpp
@@ -0,0 +1,66 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_4_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_4_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_5.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_5.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..13bc18d9ec3a2d489c915b01050d89ed90662da4
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_5.hpp
@@ -0,0 +1,78 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_5_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_5_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_6.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_6.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5a8b7bca2dd1f77723093e89e5839bb05069c876
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_6.hpp
@@ -0,0 +1,90 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_6_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_6_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_7.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_7.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..132ba86ea25ab2c7a45a88a96c10e9ab13d783ac
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_7.hpp
@@ -0,0 +1,102 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_7_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_7_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_8.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_8.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..fee51df5c7a58c521c83d3a89ea8748898ebdd5c
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_8.hpp
@@ -0,0 +1,114 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_8_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_8_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner1_9.hpp b/ThirdParty/boost/math/tools/detail/rational_horner1_9.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..994201c2ad8c6f9c1267451f15e23dbb95c70ca6
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner1_9.hpp
@@ -0,0 +1,126 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using Horners rule
+#ifndef BOOST_MATH_TOOLS_POLY_RAT_9_HPP
+#define BOOST_MATH_TOOLS_POLY_RAT_9_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((a[0] * z + a[1]) / (b[0] * z + b[1]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+     return static_cast<V>(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0]));
+   else
+   {
+      V z = 1 / x;
+      return static_cast<V>(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_10.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_10.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c08d9759b359b07efc1408869ac5689d2f685c8b
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_10.hpp
@@ -0,0 +1,144 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_10_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_10_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_11.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_11.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2256639064c56920775271f99caa8369e487ff1d
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_11.hpp
@@ -0,0 +1,160 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_11_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_11_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_12.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_12.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2e34c12e305a215ceb84175fd8053e8f96c40539
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_12.hpp
@@ -0,0 +1,176 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_12_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_12_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_13.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_13.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..85dc359bfefbbdf83ca521f8263aed1f80a69f8d
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_13.hpp
@@ -0,0 +1,192 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_13_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_13_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_14.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_14.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ef695d17b8558cfcffb66fdcdd6cf606ca5886e2
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_14.hpp
@@ -0,0 +1,208 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_14_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_14_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_15.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_15.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b77f1a20f017aeabca30a07d2a2e610353dd5957
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_15.hpp
@@ -0,0 +1,224 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_15_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_15_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_16.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_16.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d0625e07eb7f3d4a7de70684143d6e3a1fc4671a
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_16.hpp
@@ -0,0 +1,240 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_16_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_16_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_17.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_17.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3f7391da7215de5160fa02da0280f1bdbdfbe308
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_17.hpp
@@ -0,0 +1,256 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_17_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_17_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16] + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16] + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_18.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_18.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..57f76fcc2a17db0fba38e37e01d402012fa9359e
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_18.hpp
@@ -0,0 +1,272 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_18_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_18_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16] + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16] + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((((b[17] * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) / (((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_19.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_19.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..54760fb34cb16e16d52d18a0464463aa8395e07f
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_19.hpp
@@ -0,0 +1,288 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_19_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_19_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16] + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16] + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((((b[17] * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) / (((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 19>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((((b[18] * x2 + b[16]) * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((((b[17] * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z2 + a[18] + ((((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) * z) / (((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z2 + b[18] + ((((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17]) * z));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_2.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_2.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..02a4f956260b8d31625575abcc6e7c52357c2555
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_2.hpp
@@ -0,0 +1,48 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_2_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_2_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_20.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_20.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f7b7352710b276ab7581cf3e76f8f4c9f594ee83
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_20.hpp
@@ -0,0 +1,304 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_20_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_20_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16] + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16] + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((((b[17] * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) / (((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 19>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((((b[18] * x2 + b[16]) * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((((b[17] * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z2 + a[18] + ((((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) * z) / (((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z2 + b[18] + ((((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 20>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((((((((a[19] * x2 + a[17]) * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((((b[19] * x2 + b[17]) * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((((b[18] * x2 + b[16]) * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z2 + a[18]) * z + ((((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) * z2 + a[19]) / ((((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z2 + b[18]) * z + ((((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17]) * z2 + b[19]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_3.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_3.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..22a3cdeb5c7f715791514dfbe96aa1f703bb8976
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_3.hpp
@@ -0,0 +1,48 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_3_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_3_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_4.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_4.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a172df218d8301700d2d2bdba0444f122bd74367
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_4.hpp
@@ -0,0 +1,48 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_4_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_4_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_5.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_5.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5a38555bc9d7cca648abf7827a5d9fc390b2af04
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_5.hpp
@@ -0,0 +1,64 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_5_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_5_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_6.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_6.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ba67a5a44ecca76787932cfbcd1538c52d041699
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_6.hpp
@@ -0,0 +1,80 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_6_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_6_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_7.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_7.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..8d1a2991e1fd255c1f81b23a320af5104990f3ea
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_7.hpp
@@ -0,0 +1,96 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_7_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_7_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_8.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_8.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..12414a8258c6500276228f3599d42a59dd199b0e
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_8.hpp
@@ -0,0 +1,112 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_8_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_8_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner2_9.hpp b/ThirdParty/boost/math/tools/detail/rational_horner2_9.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..55b78154a0310a1f2ac9f69896104caeaa6423f8
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner2_9.hpp
@@ -0,0 +1,128 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_9_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_9_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0]));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]));
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      return static_cast<V>(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x));
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      return static_cast<V>(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z));
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_10.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_10.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f99e427541fcc6c50b9c5e25e50eac6052a4c30f
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_10.hpp
@@ -0,0 +1,396 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_10_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_10_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[4] * x2 + a[2];
+      t[1] = a[3] * x2 + a[1];
+      t[2] = b[4] * x2 + b[2];
+      t[3] = b[3] * x2 + b[1];
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[4]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[5] * x2 + a[3];
+      t[1] = a[4] * x2 + a[2];
+      t[2] = b[5] * x2 + b[3];
+      t[3] = b[4] * x2 + b[2];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[6] * x2 + a[4];
+      t[1] = a[5] * x2 + a[3];
+      t[2] = b[6] * x2 + b[4];
+      t[3] = b[5] * x2 + b[3];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[6]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[7] * x2 + a[5];
+      t[1] = a[6] * x2 + a[4];
+      t[2] = b[7] * x2 + b[5];
+      t[3] = b[6] * x2 + b[4];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[8] * x2 + a[6];
+      t[1] = a[7] * x2 + a[5];
+      t[2] = b[8] * x2 + b[6];
+      t[3] = b[7] * x2 + b[5];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[8]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[9] * x2 + a[7];
+      t[1] = a[8] * x2 + a[6];
+      t[2] = b[9] * x2 + b[7];
+      t[3] = b[8] * x2 + b[6];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_11.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_11.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d420aeeb17ea9722c1ab90144bfc78e9269e7a27
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_11.hpp
@@ -0,0 +1,482 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_11_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_11_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[4] * x2 + a[2];
+      t[1] = a[3] * x2 + a[1];
+      t[2] = b[4] * x2 + b[2];
+      t[3] = b[3] * x2 + b[1];
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[4]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[5] * x2 + a[3];
+      t[1] = a[4] * x2 + a[2];
+      t[2] = b[5] * x2 + b[3];
+      t[3] = b[4] * x2 + b[2];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[6] * x2 + a[4];
+      t[1] = a[5] * x2 + a[3];
+      t[2] = b[6] * x2 + b[4];
+      t[3] = b[5] * x2 + b[3];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[6]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[7] * x2 + a[5];
+      t[1] = a[6] * x2 + a[4];
+      t[2] = b[7] * x2 + b[5];
+      t[3] = b[6] * x2 + b[4];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[8] * x2 + a[6];
+      t[1] = a[7] * x2 + a[5];
+      t[2] = b[8] * x2 + b[6];
+      t[3] = b[7] * x2 + b[5];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[8]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[9] * x2 + a[7];
+      t[1] = a[8] * x2 + a[6];
+      t[2] = b[9] * x2 + b[7];
+      t[3] = b[8] * x2 + b[6];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[10] * x2 + a[8];
+      t[1] = a[9] * x2 + a[7];
+      t[2] = b[10] * x2 + b[8];
+      t[3] = b[9] * x2 + b[7];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[10]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_12.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_12.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4b6465b799c3be84710c5e4c8f200b641f517375
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_12.hpp
@@ -0,0 +1,576 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_12_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_12_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[4] * x2 + a[2];
+      t[1] = a[3] * x2 + a[1];
+      t[2] = b[4] * x2 + b[2];
+      t[3] = b[3] * x2 + b[1];
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[4]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[5] * x2 + a[3];
+      t[1] = a[4] * x2 + a[2];
+      t[2] = b[5] * x2 + b[3];
+      t[3] = b[4] * x2 + b[2];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[6] * x2 + a[4];
+      t[1] = a[5] * x2 + a[3];
+      t[2] = b[6] * x2 + b[4];
+      t[3] = b[5] * x2 + b[3];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[6]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[7] * x2 + a[5];
+      t[1] = a[6] * x2 + a[4];
+      t[2] = b[7] * x2 + b[5];
+      t[3] = b[6] * x2 + b[4];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[8] * x2 + a[6];
+      t[1] = a[7] * x2 + a[5];
+      t[2] = b[8] * x2 + b[6];
+      t[3] = b[7] * x2 + b[5];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[8]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[9] * x2 + a[7];
+      t[1] = a[8] * x2 + a[6];
+      t[2] = b[9] * x2 + b[7];
+      t[3] = b[8] * x2 + b[6];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[10] * x2 + a[8];
+      t[1] = a[9] * x2 + a[7];
+      t[2] = b[10] * x2 + b[8];
+      t[3] = b[9] * x2 + b[7];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[10]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[11] * x2 + a[9];
+      t[1] = a[10] * x2 + a[8];
+      t[2] = b[11] * x2 + b[9];
+      t[3] = b[10] * x2 + b[8];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_13.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_13.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..50e78dd217f6e0209ee33daf791cb8c39a792d75
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_13.hpp
@@ -0,0 +1,678 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_13_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_13_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[4] * x2 + a[2];
+      t[1] = a[3] * x2 + a[1];
+      t[2] = b[4] * x2 + b[2];
+      t[3] = b[3] * x2 + b[1];
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[4]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[5] * x2 + a[3];
+      t[1] = a[4] * x2 + a[2];
+      t[2] = b[5] * x2 + b[3];
+      t[3] = b[4] * x2 + b[2];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[6] * x2 + a[4];
+      t[1] = a[5] * x2 + a[3];
+      t[2] = b[6] * x2 + b[4];
+      t[3] = b[5] * x2 + b[3];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[6]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[7] * x2 + a[5];
+      t[1] = a[6] * x2 + a[4];
+      t[2] = b[7] * x2 + b[5];
+      t[3] = b[6] * x2 + b[4];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[8] * x2 + a[6];
+      t[1] = a[7] * x2 + a[5];
+      t[2] = b[8] * x2 + b[6];
+      t[3] = b[7] * x2 + b[5];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[8]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[9] * x2 + a[7];
+      t[1] = a[8] * x2 + a[6];
+      t[2] = b[9] * x2 + b[7];
+      t[3] = b[8] * x2 + b[6];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[10] * x2 + a[8];
+      t[1] = a[9] * x2 + a[7];
+      t[2] = b[10] * x2 + b[8];
+      t[3] = b[9] * x2 + b[7];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[10]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[11] * x2 + a[9];
+      t[1] = a[10] * x2 + a[8];
+      t[2] = b[11] * x2 + b[9];
+      t[3] = b[10] * x2 + b[8];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[12] * x2 + a[10];
+      t[1] = a[11] * x2 + a[9];
+      t[2] = b[12] * x2 + b[10];
+      t[3] = b[11] * x2 + b[9];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[2] += static_cast<V>(b[12]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_14.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_14.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f37180344ef9932fc5b9ab22f8476c8eb723518d
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_14.hpp
@@ -0,0 +1,788 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_14_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_14_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[4] * x2 + a[2];
+      t[1] = a[3] * x2 + a[1];
+      t[2] = b[4] * x2 + b[2];
+      t[3] = b[3] * x2 + b[1];
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[4]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[5] * x2 + a[3];
+      t[1] = a[4] * x2 + a[2];
+      t[2] = b[5] * x2 + b[3];
+      t[3] = b[4] * x2 + b[2];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[6] * x2 + a[4];
+      t[1] = a[5] * x2 + a[3];
+      t[2] = b[6] * x2 + b[4];
+      t[3] = b[5] * x2 + b[3];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[6]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[7] * x2 + a[5];
+      t[1] = a[6] * x2 + a[4];
+      t[2] = b[7] * x2 + b[5];
+      t[3] = b[6] * x2 + b[4];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[8] * x2 + a[6];
+      t[1] = a[7] * x2 + a[5];
+      t[2] = b[8] * x2 + b[6];
+      t[3] = b[7] * x2 + b[5];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[8]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[9] * x2 + a[7];
+      t[1] = a[8] * x2 + a[6];
+      t[2] = b[9] * x2 + b[7];
+      t[3] = b[8] * x2 + b[6];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[10] * x2 + a[8];
+      t[1] = a[9] * x2 + a[7];
+      t[2] = b[10] * x2 + b[8];
+      t[3] = b[9] * x2 + b[7];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[10]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[11] * x2 + a[9];
+      t[1] = a[10] * x2 + a[8];
+      t[2] = b[11] * x2 + b[9];
+      t[3] = b[10] * x2 + b[8];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[12] * x2 + a[10];
+      t[1] = a[11] * x2 + a[9];
+      t[2] = b[12] * x2 + b[10];
+      t[3] = b[11] * x2 + b[9];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[2] += static_cast<V>(b[12]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[13] * x2 + a[11];
+      t[1] = a[12] * x2 + a[10];
+      t[2] = b[13] * x2 + b[11];
+      t[3] = b[12] * x2 + b[10];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[9]);
+      t[1] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[9]);
+      t[3] += static_cast<V>(b[8]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_15.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_15.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7f123647872937f0ef9b6fff7dcf0884ea5f5f7d
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_15.hpp
@@ -0,0 +1,906 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_15_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_15_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[4] * x2 + a[2];
+      t[1] = a[3] * x2 + a[1];
+      t[2] = b[4] * x2 + b[2];
+      t[3] = b[3] * x2 + b[1];
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[4]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[5] * x2 + a[3];
+      t[1] = a[4] * x2 + a[2];
+      t[2] = b[5] * x2 + b[3];
+      t[3] = b[4] * x2 + b[2];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[6] * x2 + a[4];
+      t[1] = a[5] * x2 + a[3];
+      t[2] = b[6] * x2 + b[4];
+      t[3] = b[5] * x2 + b[3];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[6]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[7] * x2 + a[5];
+      t[1] = a[6] * x2 + a[4];
+      t[2] = b[7] * x2 + b[5];
+      t[3] = b[6] * x2 + b[4];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[8] * x2 + a[6];
+      t[1] = a[7] * x2 + a[5];
+      t[2] = b[8] * x2 + b[6];
+      t[3] = b[7] * x2 + b[5];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[8]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[9] * x2 + a[7];
+      t[1] = a[8] * x2 + a[6];
+      t[2] = b[9] * x2 + b[7];
+      t[3] = b[8] * x2 + b[6];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[10] * x2 + a[8];
+      t[1] = a[9] * x2 + a[7];
+      t[2] = b[10] * x2 + b[8];
+      t[3] = b[9] * x2 + b[7];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[10]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[11] * x2 + a[9];
+      t[1] = a[10] * x2 + a[8];
+      t[2] = b[11] * x2 + b[9];
+      t[3] = b[10] * x2 + b[8];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[12] * x2 + a[10];
+      t[1] = a[11] * x2 + a[9];
+      t[2] = b[12] * x2 + b[10];
+      t[3] = b[11] * x2 + b[9];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[2] += static_cast<V>(b[12]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[13] * x2 + a[11];
+      t[1] = a[12] * x2 + a[10];
+      t[2] = b[13] * x2 + b[11];
+      t[3] = b[12] * x2 + b[10];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[9]);
+      t[1] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[9]);
+      t[3] += static_cast<V>(b[8]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[14] * x2 + a[12];
+      t[1] = a[13] * x2 + a[11];
+      t[2] = b[14] * x2 + b[12];
+      t[3] = b[13] * x2 + b[11];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[2] += static_cast<V>(b[14]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_16.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_16.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..23221e1834494f0795fa3d6e7a27b5dc8df25afa
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_16.hpp
@@ -0,0 +1,1032 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_16_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_16_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[4] * x2 + a[2];
+      t[1] = a[3] * x2 + a[1];
+      t[2] = b[4] * x2 + b[2];
+      t[3] = b[3] * x2 + b[1];
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[4]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[5] * x2 + a[3];
+      t[1] = a[4] * x2 + a[2];
+      t[2] = b[5] * x2 + b[3];
+      t[3] = b[4] * x2 + b[2];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[6] * x2 + a[4];
+      t[1] = a[5] * x2 + a[3];
+      t[2] = b[6] * x2 + b[4];
+      t[3] = b[5] * x2 + b[3];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[6]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[7] * x2 + a[5];
+      t[1] = a[6] * x2 + a[4];
+      t[2] = b[7] * x2 + b[5];
+      t[3] = b[6] * x2 + b[4];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[8] * x2 + a[6];
+      t[1] = a[7] * x2 + a[5];
+      t[2] = b[8] * x2 + b[6];
+      t[3] = b[7] * x2 + b[5];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[8]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[9] * x2 + a[7];
+      t[1] = a[8] * x2 + a[6];
+      t[2] = b[9] * x2 + b[7];
+      t[3] = b[8] * x2 + b[6];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[10] * x2 + a[8];
+      t[1] = a[9] * x2 + a[7];
+      t[2] = b[10] * x2 + b[8];
+      t[3] = b[9] * x2 + b[7];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[10]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[11] * x2 + a[9];
+      t[1] = a[10] * x2 + a[8];
+      t[2] = b[11] * x2 + b[9];
+      t[3] = b[10] * x2 + b[8];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[12] * x2 + a[10];
+      t[1] = a[11] * x2 + a[9];
+      t[2] = b[12] * x2 + b[10];
+      t[3] = b[11] * x2 + b[9];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[2] += static_cast<V>(b[12]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[13] * x2 + a[11];
+      t[1] = a[12] * x2 + a[10];
+      t[2] = b[13] * x2 + b[11];
+      t[3] = b[12] * x2 + b[10];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[9]);
+      t[1] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[9]);
+      t[3] += static_cast<V>(b[8]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[14] * x2 + a[12];
+      t[1] = a[13] * x2 + a[11];
+      t[2] = b[14] * x2 + b[12];
+      t[3] = b[13] * x2 + b[11];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[2] += static_cast<V>(b[14]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[15] * x2 + a[13];
+      t[1] = a[14] * x2 + a[12];
+      t[2] = b[15] * x2 + b[13];
+      t[3] = b[14] * x2 + b[12];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[11]);
+      t[1] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[11]);
+      t[3] += static_cast<V>(b[10]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[9]);
+      t[1] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[9]);
+      t[3] += static_cast<V>(b[8]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[1] += static_cast<V>(a[15]);
+      t[2] += static_cast<V>(b[14]);
+      t[3] += static_cast<V>(b[15]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_17.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_17.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f1246c45a9fdb0ddca6542808c8146655e59af65
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_17.hpp
@@ -0,0 +1,1166 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_17_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_17_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[4] * x2 + a[2];
+      t[1] = a[3] * x2 + a[1];
+      t[2] = b[4] * x2 + b[2];
+      t[3] = b[3] * x2 + b[1];
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[4]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[5] * x2 + a[3];
+      t[1] = a[4] * x2 + a[2];
+      t[2] = b[5] * x2 + b[3];
+      t[3] = b[4] * x2 + b[2];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[6] * x2 + a[4];
+      t[1] = a[5] * x2 + a[3];
+      t[2] = b[6] * x2 + b[4];
+      t[3] = b[5] * x2 + b[3];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[6]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[7] * x2 + a[5];
+      t[1] = a[6] * x2 + a[4];
+      t[2] = b[7] * x2 + b[5];
+      t[3] = b[6] * x2 + b[4];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[8] * x2 + a[6];
+      t[1] = a[7] * x2 + a[5];
+      t[2] = b[8] * x2 + b[6];
+      t[3] = b[7] * x2 + b[5];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[8]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[9] * x2 + a[7];
+      t[1] = a[8] * x2 + a[6];
+      t[2] = b[9] * x2 + b[7];
+      t[3] = b[8] * x2 + b[6];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[10] * x2 + a[8];
+      t[1] = a[9] * x2 + a[7];
+      t[2] = b[10] * x2 + b[8];
+      t[3] = b[9] * x2 + b[7];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[10]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[11] * x2 + a[9];
+      t[1] = a[10] * x2 + a[8];
+      t[2] = b[11] * x2 + b[9];
+      t[3] = b[10] * x2 + b[8];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[12] * x2 + a[10];
+      t[1] = a[11] * x2 + a[9];
+      t[2] = b[12] * x2 + b[10];
+      t[3] = b[11] * x2 + b[9];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[2] += static_cast<V>(b[12]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[13] * x2 + a[11];
+      t[1] = a[12] * x2 + a[10];
+      t[2] = b[13] * x2 + b[11];
+      t[3] = b[12] * x2 + b[10];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[9]);
+      t[1] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[9]);
+      t[3] += static_cast<V>(b[8]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[14] * x2 + a[12];
+      t[1] = a[13] * x2 + a[11];
+      t[2] = b[14] * x2 + b[12];
+      t[3] = b[13] * x2 + b[11];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[2] += static_cast<V>(b[14]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[15] * x2 + a[13];
+      t[1] = a[14] * x2 + a[12];
+      t[2] = b[15] * x2 + b[13];
+      t[3] = b[14] * x2 + b[12];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[11]);
+      t[1] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[11]);
+      t[3] += static_cast<V>(b[10]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[9]);
+      t[1] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[9]);
+      t[3] += static_cast<V>(b[8]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[1] += static_cast<V>(a[15]);
+      t[2] += static_cast<V>(b[14]);
+      t[3] += static_cast<V>(b[15]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[16] * x2 + a[14];
+      t[1] = a[15] * x2 + a[13];
+      t[2] = b[16] * x2 + b[14];
+      t[3] = b[15] * x2 + b[13];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[1] += static_cast<V>(a[15]);
+      t[2] += static_cast<V>(b[14]);
+      t[3] += static_cast<V>(b[15]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[16]);
+      t[2] += static_cast<V>(b[16]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_18.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_18.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..0af4d47b7a2b7ed25a88e061da2ad25048ba6404
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_18.hpp
@@ -0,0 +1,1308 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_18_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_18_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[4] * x2 + a[2];
+      t[1] = a[3] * x2 + a[1];
+      t[2] = b[4] * x2 + b[2];
+      t[3] = b[3] * x2 + b[1];
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[4]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[5] * x2 + a[3];
+      t[1] = a[4] * x2 + a[2];
+      t[2] = b[5] * x2 + b[3];
+      t[3] = b[4] * x2 + b[2];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[6] * x2 + a[4];
+      t[1] = a[5] * x2 + a[3];
+      t[2] = b[6] * x2 + b[4];
+      t[3] = b[5] * x2 + b[3];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[6]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[7] * x2 + a[5];
+      t[1] = a[6] * x2 + a[4];
+      t[2] = b[7] * x2 + b[5];
+      t[3] = b[6] * x2 + b[4];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[8] * x2 + a[6];
+      t[1] = a[7] * x2 + a[5];
+      t[2] = b[8] * x2 + b[6];
+      t[3] = b[7] * x2 + b[5];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[8]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[9] * x2 + a[7];
+      t[1] = a[8] * x2 + a[6];
+      t[2] = b[9] * x2 + b[7];
+      t[3] = b[8] * x2 + b[6];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[10] * x2 + a[8];
+      t[1] = a[9] * x2 + a[7];
+      t[2] = b[10] * x2 + b[8];
+      t[3] = b[9] * x2 + b[7];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[10]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[11] * x2 + a[9];
+      t[1] = a[10] * x2 + a[8];
+      t[2] = b[11] * x2 + b[9];
+      t[3] = b[10] * x2 + b[8];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[12] * x2 + a[10];
+      t[1] = a[11] * x2 + a[9];
+      t[2] = b[12] * x2 + b[10];
+      t[3] = b[11] * x2 + b[9];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[2] += static_cast<V>(b[12]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[13] * x2 + a[11];
+      t[1] = a[12] * x2 + a[10];
+      t[2] = b[13] * x2 + b[11];
+      t[3] = b[12] * x2 + b[10];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[9]);
+      t[1] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[9]);
+      t[3] += static_cast<V>(b[8]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[14] * x2 + a[12];
+      t[1] = a[13] * x2 + a[11];
+      t[2] = b[14] * x2 + b[12];
+      t[3] = b[13] * x2 + b[11];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[2] += static_cast<V>(b[14]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[15] * x2 + a[13];
+      t[1] = a[14] * x2 + a[12];
+      t[2] = b[15] * x2 + b[13];
+      t[3] = b[14] * x2 + b[12];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[11]);
+      t[1] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[11]);
+      t[3] += static_cast<V>(b[10]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[9]);
+      t[1] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[9]);
+      t[3] += static_cast<V>(b[8]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[1] += static_cast<V>(a[15]);
+      t[2] += static_cast<V>(b[14]);
+      t[3] += static_cast<V>(b[15]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[16] * x2 + a[14];
+      t[1] = a[15] * x2 + a[13];
+      t[2] = b[16] * x2 + b[14];
+      t[3] = b[15] * x2 + b[13];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[1] += static_cast<V>(a[15]);
+      t[2] += static_cast<V>(b[14]);
+      t[3] += static_cast<V>(b[15]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[16]);
+      t[2] += static_cast<V>(b[16]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[17] * x2 + a[15];
+      t[1] = a[16] * x2 + a[14];
+      t[2] = b[17] * x2 + b[15];
+      t[3] = b[16] * x2 + b[14];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[13]);
+      t[1] += static_cast<V>(a[12]);
+      t[2] += static_cast<V>(b[13]);
+      t[3] += static_cast<V>(b[12]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[11]);
+      t[1] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[11]);
+      t[3] += static_cast<V>(b[10]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[9]);
+      t[1] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[9]);
+      t[3] += static_cast<V>(b[8]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[1] += static_cast<V>(a[15]);
+      t[2] += static_cast<V>(b[14]);
+      t[3] += static_cast<V>(b[15]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[16]);
+      t[1] += static_cast<V>(a[17]);
+      t[2] += static_cast<V>(b[16]);
+      t[3] += static_cast<V>(b[17]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_19.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_19.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d0d675df80f081ffac6d5228cfeee4e2e490503d
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_19.hpp
@@ -0,0 +1,1458 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_19_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_19_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[4] * x2 + a[2];
+      t[1] = a[3] * x2 + a[1];
+      t[2] = b[4] * x2 + b[2];
+      t[3] = b[3] * x2 + b[1];
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[4]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[5] * x2 + a[3];
+      t[1] = a[4] * x2 + a[2];
+      t[2] = b[5] * x2 + b[3];
+      t[3] = b[4] * x2 + b[2];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[6] * x2 + a[4];
+      t[1] = a[5] * x2 + a[3];
+      t[2] = b[6] * x2 + b[4];
+      t[3] = b[5] * x2 + b[3];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[6]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[7] * x2 + a[5];
+      t[1] = a[6] * x2 + a[4];
+      t[2] = b[7] * x2 + b[5];
+      t[3] = b[6] * x2 + b[4];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[8] * x2 + a[6];
+      t[1] = a[7] * x2 + a[5];
+      t[2] = b[8] * x2 + b[6];
+      t[3] = b[7] * x2 + b[5];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[8]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[9] * x2 + a[7];
+      t[1] = a[8] * x2 + a[6];
+      t[2] = b[9] * x2 + b[7];
+      t[3] = b[8] * x2 + b[6];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[10] * x2 + a[8];
+      t[1] = a[9] * x2 + a[7];
+      t[2] = b[10] * x2 + b[8];
+      t[3] = b[9] * x2 + b[7];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[10]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[11] * x2 + a[9];
+      t[1] = a[10] * x2 + a[8];
+      t[2] = b[11] * x2 + b[9];
+      t[3] = b[10] * x2 + b[8];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[12] * x2 + a[10];
+      t[1] = a[11] * x2 + a[9];
+      t[2] = b[12] * x2 + b[10];
+      t[3] = b[11] * x2 + b[9];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[2] += static_cast<V>(b[12]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[13] * x2 + a[11];
+      t[1] = a[12] * x2 + a[10];
+      t[2] = b[13] * x2 + b[11];
+      t[3] = b[12] * x2 + b[10];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[9]);
+      t[1] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[9]);
+      t[3] += static_cast<V>(b[8]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[14] * x2 + a[12];
+      t[1] = a[13] * x2 + a[11];
+      t[2] = b[14] * x2 + b[12];
+      t[3] = b[13] * x2 + b[11];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[2] += static_cast<V>(b[14]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[15] * x2 + a[13];
+      t[1] = a[14] * x2 + a[12];
+      t[2] = b[15] * x2 + b[13];
+      t[3] = b[14] * x2 + b[12];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[11]);
+      t[1] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[11]);
+      t[3] += static_cast<V>(b[10]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[9]);
+      t[1] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[9]);
+      t[3] += static_cast<V>(b[8]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[1] += static_cast<V>(a[15]);
+      t[2] += static_cast<V>(b[14]);
+      t[3] += static_cast<V>(b[15]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[16] * x2 + a[14];
+      t[1] = a[15] * x2 + a[13];
+      t[2] = b[16] * x2 + b[14];
+      t[3] = b[15] * x2 + b[13];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[1] += static_cast<V>(a[15]);
+      t[2] += static_cast<V>(b[14]);
+      t[3] += static_cast<V>(b[15]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[16]);
+      t[2] += static_cast<V>(b[16]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[17] * x2 + a[15];
+      t[1] = a[16] * x2 + a[14];
+      t[2] = b[17] * x2 + b[15];
+      t[3] = b[16] * x2 + b[14];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[13]);
+      t[1] += static_cast<V>(a[12]);
+      t[2] += static_cast<V>(b[13]);
+      t[3] += static_cast<V>(b[12]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[11]);
+      t[1] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[11]);
+      t[3] += static_cast<V>(b[10]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[9]);
+      t[1] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[9]);
+      t[3] += static_cast<V>(b[8]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[1] += static_cast<V>(a[15]);
+      t[2] += static_cast<V>(b[14]);
+      t[3] += static_cast<V>(b[15]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[16]);
+      t[1] += static_cast<V>(a[17]);
+      t[2] += static_cast<V>(b[16]);
+      t[3] += static_cast<V>(b[17]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 19>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[18] * x2 + a[16];
+      t[1] = a[17] * x2 + a[15];
+      t[2] = b[18] * x2 + b[16];
+      t[3] = b[17] * x2 + b[15];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[14]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[14]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[1] += static_cast<V>(a[15]);
+      t[2] += static_cast<V>(b[14]);
+      t[3] += static_cast<V>(b[15]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[16]);
+      t[1] += static_cast<V>(a[17]);
+      t[2] += static_cast<V>(b[16]);
+      t[3] += static_cast<V>(b[17]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[18]);
+      t[2] += static_cast<V>(b[18]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_2.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_2.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..02a4f956260b8d31625575abcc6e7c52357c2555
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_2.hpp
@@ -0,0 +1,48 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_2_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_2_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_20.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_20.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..187d83a39afc224796b2cec551cb0437be66f902
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_20.hpp
@@ -0,0 +1,1616 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_20_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_20_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[4] * x2 + a[2];
+      t[1] = a[3] * x2 + a[1];
+      t[2] = b[4] * x2 + b[2];
+      t[3] = b[3] * x2 + b[1];
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[4]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[5] * x2 + a[3];
+      t[1] = a[4] * x2 + a[2];
+      t[2] = b[5] * x2 + b[3];
+      t[3] = b[4] * x2 + b[2];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[6] * x2 + a[4];
+      t[1] = a[5] * x2 + a[3];
+      t[2] = b[6] * x2 + b[4];
+      t[3] = b[5] * x2 + b[3];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[6]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[7] * x2 + a[5];
+      t[1] = a[6] * x2 + a[4];
+      t[2] = b[7] * x2 + b[5];
+      t[3] = b[6] * x2 + b[4];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[8] * x2 + a[6];
+      t[1] = a[7] * x2 + a[5];
+      t[2] = b[8] * x2 + b[6];
+      t[3] = b[7] * x2 + b[5];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[8]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 10>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[9] * x2 + a[7];
+      t[1] = a[8] * x2 + a[6];
+      t[2] = b[9] * x2 + b[7];
+      t[3] = b[8] * x2 + b[6];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 11>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[10] * x2 + a[8];
+      t[1] = a[9] * x2 + a[7];
+      t[2] = b[10] * x2 + b[8];
+      t[3] = b[9] * x2 + b[7];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[10]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 12>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[11] * x2 + a[9];
+      t[1] = a[10] * x2 + a[8];
+      t[2] = b[11] * x2 + b[9];
+      t[3] = b[10] * x2 + b[8];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 13>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[12] * x2 + a[10];
+      t[1] = a[11] * x2 + a[9];
+      t[2] = b[12] * x2 + b[10];
+      t[3] = b[11] * x2 + b[9];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[2] += static_cast<V>(b[12]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 14>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[13] * x2 + a[11];
+      t[1] = a[12] * x2 + a[10];
+      t[2] = b[13] * x2 + b[11];
+      t[3] = b[12] * x2 + b[10];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[9]);
+      t[1] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[9]);
+      t[3] += static_cast<V>(b[8]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 15>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[14] * x2 + a[12];
+      t[1] = a[13] * x2 + a[11];
+      t[2] = b[14] * x2 + b[12];
+      t[3] = b[13] * x2 + b[11];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[2] += static_cast<V>(b[14]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 16>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[15] * x2 + a[13];
+      t[1] = a[14] * x2 + a[12];
+      t[2] = b[15] * x2 + b[13];
+      t[3] = b[14] * x2 + b[12];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[11]);
+      t[1] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[11]);
+      t[3] += static_cast<V>(b[10]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[9]);
+      t[1] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[9]);
+      t[3] += static_cast<V>(b[8]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[1] += static_cast<V>(a[15]);
+      t[2] += static_cast<V>(b[14]);
+      t[3] += static_cast<V>(b[15]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 17>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[16] * x2 + a[14];
+      t[1] = a[15] * x2 + a[13];
+      t[2] = b[16] * x2 + b[14];
+      t[3] = b[15] * x2 + b[13];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[1] += static_cast<V>(a[15]);
+      t[2] += static_cast<V>(b[14]);
+      t[3] += static_cast<V>(b[15]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[16]);
+      t[2] += static_cast<V>(b[16]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 18>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[17] * x2 + a[15];
+      t[1] = a[16] * x2 + a[14];
+      t[2] = b[17] * x2 + b[15];
+      t[3] = b[16] * x2 + b[14];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[13]);
+      t[1] += static_cast<V>(a[12]);
+      t[2] += static_cast<V>(b[13]);
+      t[3] += static_cast<V>(b[12]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[11]);
+      t[1] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[11]);
+      t[3] += static_cast<V>(b[10]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[9]);
+      t[1] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[9]);
+      t[3] += static_cast<V>(b[8]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[1] += static_cast<V>(a[15]);
+      t[2] += static_cast<V>(b[14]);
+      t[3] += static_cast<V>(b[15]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[16]);
+      t[1] += static_cast<V>(a[17]);
+      t[2] += static_cast<V>(b[16]);
+      t[3] += static_cast<V>(b[17]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 19>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[18] * x2 + a[16];
+      t[1] = a[17] * x2 + a[15];
+      t[2] = b[18] * x2 + b[16];
+      t[3] = b[17] * x2 + b[15];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[14]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[14]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[1] += static_cast<V>(a[15]);
+      t[2] += static_cast<V>(b[14]);
+      t[3] += static_cast<V>(b[15]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[16]);
+      t[1] += static_cast<V>(a[17]);
+      t[2] += static_cast<V>(b[16]);
+      t[3] += static_cast<V>(b[17]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[18]);
+      t[2] += static_cast<V>(b[18]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 20>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[19] * x2 + a[17];
+      t[1] = a[18] * x2 + a[16];
+      t[2] = b[19] * x2 + b[17];
+      t[3] = b[18] * x2 + b[16];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[15]);
+      t[1] += static_cast<V>(a[14]);
+      t[2] += static_cast<V>(b[15]);
+      t[3] += static_cast<V>(b[14]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[13]);
+      t[1] += static_cast<V>(a[12]);
+      t[2] += static_cast<V>(b[13]);
+      t[3] += static_cast<V>(b[12]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[11]);
+      t[1] += static_cast<V>(a[10]);
+      t[2] += static_cast<V>(b[11]);
+      t[3] += static_cast<V>(b[10]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[9]);
+      t[1] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[9]);
+      t[3] += static_cast<V>(b[8]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[7]);
+      t[1] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[7]);
+      t[3] += static_cast<V>(b[6]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[5]);
+      t[1] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[5]);
+      t[3] += static_cast<V>(b[4]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[1] += static_cast<V>(a[9]);
+      t[2] += static_cast<V>(b[8]);
+      t[3] += static_cast<V>(b[9]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[10]);
+      t[1] += static_cast<V>(a[11]);
+      t[2] += static_cast<V>(b[10]);
+      t[3] += static_cast<V>(b[11]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[12]);
+      t[1] += static_cast<V>(a[13]);
+      t[2] += static_cast<V>(b[12]);
+      t[3] += static_cast<V>(b[13]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[14]);
+      t[1] += static_cast<V>(a[15]);
+      t[2] += static_cast<V>(b[14]);
+      t[3] += static_cast<V>(b[15]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[16]);
+      t[1] += static_cast<V>(a[17]);
+      t[2] += static_cast<V>(b[16]);
+      t[3] += static_cast<V>(b[17]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[18]);
+      t[1] += static_cast<V>(a[19]);
+      t[2] += static_cast<V>(b[18]);
+      t[3] += static_cast<V>(b[19]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_3.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_3.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..22a3cdeb5c7f715791514dfbe96aa1f703bb8976
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_3.hpp
@@ -0,0 +1,48 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_3_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_3_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_4.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_4.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a172df218d8301700d2d2bdba0444f122bd74367
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_4.hpp
@@ -0,0 +1,48 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_4_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_4_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_5.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_5.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7eae160a08d3bc490aba5aa93260957643496c32
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_5.hpp
@@ -0,0 +1,86 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_5_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_5_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[4] * x2 + a[2];
+      t[1] = a[3] * x2 + a[1];
+      t[2] = b[4] * x2 + b[2];
+      t[3] = b[3] * x2 + b[1];
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[4]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_6.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_6.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9bfa94c09aae78d137389b575963c3aee05d9eec
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_6.hpp
@@ -0,0 +1,132 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_6_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_6_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[4] * x2 + a[2];
+      t[1] = a[3] * x2 + a[1];
+      t[2] = b[4] * x2 + b[2];
+      t[3] = b[3] * x2 + b[1];
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[4]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[5] * x2 + a[3];
+      t[1] = a[4] * x2 + a[2];
+      t[2] = b[5] * x2 + b[3];
+      t[3] = b[4] * x2 + b[2];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_7.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_7.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9f9212816d52aca1ad3bb1a62b3ec9f905c42ff2
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_7.hpp
@@ -0,0 +1,186 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_7_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_7_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[4] * x2 + a[2];
+      t[1] = a[3] * x2 + a[1];
+      t[2] = b[4] * x2 + b[2];
+      t[3] = b[3] * x2 + b[1];
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[4]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[5] * x2 + a[3];
+      t[1] = a[4] * x2 + a[2];
+      t[2] = b[5] * x2 + b[3];
+      t[3] = b[4] * x2 + b[2];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[6] * x2 + a[4];
+      t[1] = a[5] * x2 + a[3];
+      t[2] = b[6] * x2 + b[4];
+      t[3] = b[5] * x2 + b[3];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[6]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_8.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_8.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..13ad80c5a701787268724f89f27090a60f94032b
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_8.hpp
@@ -0,0 +1,248 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_8_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_8_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[4] * x2 + a[2];
+      t[1] = a[3] * x2 + a[1];
+      t[2] = b[4] * x2 + b[2];
+      t[3] = b[3] * x2 + b[1];
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[4]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[5] * x2 + a[3];
+      t[1] = a[4] * x2 + a[2];
+      t[2] = b[5] * x2 + b[3];
+      t[3] = b[4] * x2 + b[2];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[6] * x2 + a[4];
+      t[1] = a[5] * x2 + a[3];
+      t[2] = b[6] * x2 + b[4];
+      t[3] = b[5] * x2 + b[3];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[6]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[7] * x2 + a[5];
+      t[1] = a[6] * x2 + a[4];
+      t[2] = b[7] * x2 + b[5];
+      t[3] = b[6] * x2 + b[4];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/detail/rational_horner3_9.hpp b/ThirdParty/boost/math/tools/detail/rational_horner3_9.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f2de56a640805ca0d10703d14bb137843183323e
--- /dev/null
+++ b/ThirdParty/boost/math/tools/detail/rational_horner3_9.hpp
@@ -0,0 +1,318 @@
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to 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)
+//
+//  This file is machine generated, do not edit by hand
+
+// Polynomial evaluation using second order Horners rule
+#ifndef BOOST_MATH_TOOLS_RAT_EVAL_9_HPP
+#define BOOST_MATH_TOOLS_RAT_EVAL_9_HPP
+
+namespace boost{ namespace math{ namespace tools{ namespace detail{
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T*, const U*, const V&, const boost::integral_constant<int, 0>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(0);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const boost::integral_constant<int, 1>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(a[0]) / static_cast<V>(b[0]);
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 2>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 3>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 4>*) BOOST_MATH_NOEXCEPT(V)
+{
+   return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 5>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[4] * x2 + a[2];
+      t[1] = a[3] * x2 + a[1];
+      t[2] = b[4] * x2 + b[2];
+      t[3] = b[3] * x2 + b[1];
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[2] += static_cast<V>(b[4]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 6>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[5] * x2 + a[3];
+      t[1] = a[4] * x2 + a[2];
+      t[2] = b[5] * x2 + b[3];
+      t[3] = b[4] * x2 + b[2];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 7>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[6] * x2 + a[4];
+      t[1] = a[5] * x2 + a[3];
+      t[2] = b[6] * x2 + b[4];
+      t[3] = b[5] * x2 + b[3];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[2] += static_cast<V>(b[6]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 8>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[7] * x2 + a[5];
+      t[1] = a[6] * x2 + a[4];
+      t[2] = b[7] * x2 + b[5];
+      t[3] = b[6] * x2 + b[4];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[3]);
+      t[1] += static_cast<V>(a[2]);
+      t[2] += static_cast<V>(b[3]);
+      t[3] += static_cast<V>(b[2]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[1]);
+      t[1] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[1]);
+      t[3] += static_cast<V>(b[0]);
+      t[0] *= x;
+      t[2] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z;
+      t[2] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+template <class T, class U, class V>
+inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const boost::integral_constant<int, 9>*) BOOST_MATH_NOEXCEPT(V)
+{
+   if(x <= 1)
+   {
+      V x2 = x * x;
+      V t[4];
+      t[0] = a[8] * x2 + a[6];
+      t[1] = a[7] * x2 + a[5];
+      t[2] = b[8] * x2 + b[6];
+      t[3] = b[7] * x2 + b[5];
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[3]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[3]);
+      t[0] *= x2;
+      t[1] *= x2;
+      t[2] *= x2;
+      t[3] *= x2;
+      t[0] += static_cast<V>(a[2]);
+      t[1] += static_cast<V>(a[1]);
+      t[2] += static_cast<V>(b[2]);
+      t[3] += static_cast<V>(b[1]);
+      t[0] *= x2;
+      t[2] *= x2;
+      t[0] += static_cast<V>(a[0]);
+      t[2] += static_cast<V>(b[0]);
+      t[1] *= x;
+      t[3] *= x;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+   else
+   {
+      V z = 1 / x;
+      V z2 = 1 / (x * x);
+      V t[4];
+      t[0] = a[0] * z2 + a[2];
+      t[1] = a[1] * z2 + a[3];
+      t[2] = b[0] * z2 + b[2];
+      t[3] = b[1] * z2 + b[3];
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[4]);
+      t[1] += static_cast<V>(a[5]);
+      t[2] += static_cast<V>(b[4]);
+      t[3] += static_cast<V>(b[5]);
+      t[0] *= z2;
+      t[1] *= z2;
+      t[2] *= z2;
+      t[3] *= z2;
+      t[0] += static_cast<V>(a[6]);
+      t[1] += static_cast<V>(a[7]);
+      t[2] += static_cast<V>(b[6]);
+      t[3] += static_cast<V>(b[7]);
+      t[0] *= z2;
+      t[2] *= z2;
+      t[0] += static_cast<V>(a[8]);
+      t[2] += static_cast<V>(b[8]);
+      t[1] *= z;
+      t[3] *= z;
+      return (t[0] + t[1]) / (t[2] + t[3]);
+   }
+}
+
+
+}}}} // namespaces
+
+#endif // include guard
+
diff --git a/ThirdParty/boost/math/tools/fraction.hpp b/ThirdParty/boost/math/tools/fraction.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..65733029bb4026ab8c2790069e93e175c39d48e3
--- /dev/null
+++ b/ThirdParty/boost/math/tools/fraction.hpp
@@ -0,0 +1,287 @@
+//  (C) Copyright John Maddock 2005-2006.
+//  Use, modification and distribution are subject to 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_TOOLS_FRACTION_INCLUDED
+#define BOOST_MATH_TOOLS_FRACTION_INCLUDED
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/math/tools/precision.hpp>
+#include <boost/math/tools/complex.hpp>
+
+namespace boost{ namespace math{ namespace tools{
+
+namespace detail
+{
+
+   template <class T>
+   struct is_pair : public boost::false_type{};
+
+   template <class T, class U>
+   struct is_pair<std::pair<T,U> > : public boost::true_type{};
+
+   template <class Gen>
+   struct fraction_traits_simple
+   {
+       typedef typename Gen::result_type result_type;
+       typedef typename Gen::result_type value_type;
+
+       static result_type a(const value_type&) BOOST_MATH_NOEXCEPT(value_type)
+       {
+          return 1;
+       }
+       static result_type b(const value_type& v) BOOST_MATH_NOEXCEPT(value_type)
+       {
+          return v;
+       }
+   };
+
+   template <class Gen>
+   struct fraction_traits_pair
+   {
+       typedef typename Gen::result_type value_type;
+       typedef typename value_type::first_type result_type;
+
+       static result_type a(const value_type& v) BOOST_MATH_NOEXCEPT(value_type)
+       {
+          return v.first;
+       }
+       static result_type b(const value_type& v) BOOST_MATH_NOEXCEPT(value_type)
+       {
+          return v.second;
+       }
+   };
+
+   template <class Gen>
+   struct fraction_traits
+       : public boost::mpl::if_c<
+         is_pair<typename Gen::result_type>::value,
+         fraction_traits_pair<Gen>,
+         fraction_traits_simple<Gen> >::type
+   {
+   };
+
+   template <class T, bool = is_complex_type<T>::value>
+   struct tiny_value
+   {
+      static T get() {
+         return tools::min_value<T>(); 
+      }
+   };
+   template <class T>
+   struct tiny_value<T, true>
+   {
+      typedef typename T::value_type value_type;
+      static T get() {
+         return tools::min_value<value_type>();
+      }
+   };
+
+} // namespace detail
+
+//
+// continued_fraction_b
+// Evaluates:
+//
+// b0 +       a1
+//      ---------------
+//      b1 +     a2
+//           ----------
+//           b2 +   a3
+//                -----
+//                b3 + ...
+//
+// Note that the first a0 returned by generator Gen is discarded.
+//
+template <class Gen, class U>
+inline typename detail::fraction_traits<Gen>::result_type continued_fraction_b(Gen& g, const U& factor, boost::uintmax_t& max_terms) 
+      BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits<Gen>::result_type) && noexcept(std::declval<Gen>()()))
+{
+   BOOST_MATH_STD_USING // ADL of std names
+
+   typedef detail::fraction_traits<Gen> traits;
+   typedef typename traits::result_type result_type;
+   typedef typename traits::value_type value_type;
+   typedef typename integer_scalar_type<result_type>::type integer_type;
+   typedef typename scalar_type<result_type>::type scalar_type;
+
+   integer_type const zero(0), one(1);
+
+   result_type tiny = detail::tiny_value<result_type>::get();
+   scalar_type terminator = abs(factor);
+
+   value_type v = g();
+
+   result_type f, C, D, delta;
+   f = traits::b(v);
+   if(f == zero)
+      f = tiny;
+   C = f;
+   D = 0;
+
+   boost::uintmax_t counter(max_terms);
+
+   do{
+      v = g();
+      D = traits::b(v) + traits::a(v) * D;
+      if(D == result_type(0))
+         D = tiny;
+      C = traits::b(v) + traits::a(v) / C;
+      if(C == zero)
+         C = tiny;
+      D = one/D;
+      delta = C*D;
+      f = f * delta;
+   }while((abs(delta - one) > terminator) && --counter);
+
+   max_terms = max_terms - counter;
+
+   return f;
+}
+
+template <class Gen, class U>
+inline typename detail::fraction_traits<Gen>::result_type continued_fraction_b(Gen& g, const U& factor)
+   BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits<Gen>::result_type) && noexcept(std::declval<Gen>()()))
+{
+   boost::uintmax_t max_terms = (std::numeric_limits<boost::uintmax_t>::max)();
+   return continued_fraction_b(g, factor, max_terms);
+}
+
+template <class Gen>
+inline typename detail::fraction_traits<Gen>::result_type continued_fraction_b(Gen& g, int bits)
+   BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits<Gen>::result_type) && noexcept(std::declval<Gen>()()))
+{
+   BOOST_MATH_STD_USING // ADL of std names
+
+   typedef detail::fraction_traits<Gen> traits;
+   typedef typename traits::result_type result_type;
+
+   result_type factor = ldexp(1.0f, 1 - bits); // 1 / pow(result_type(2), bits);
+   boost::uintmax_t max_terms = (std::numeric_limits<boost::uintmax_t>::max)();
+   return continued_fraction_b(g, factor, max_terms);
+}
+
+template <class Gen>
+inline typename detail::fraction_traits<Gen>::result_type continued_fraction_b(Gen& g, int bits, boost::uintmax_t& max_terms)
+   BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits<Gen>::result_type) && noexcept(std::declval<Gen>()()))
+{
+   BOOST_MATH_STD_USING // ADL of std names
+
+   typedef detail::fraction_traits<Gen> traits;
+   typedef typename traits::result_type result_type;
+
+   result_type factor = ldexp(1.0f, 1 - bits); // 1 / pow(result_type(2), bits);
+   return continued_fraction_b(g, factor, max_terms);
+}
+
+//
+// continued_fraction_a
+// Evaluates:
+//
+//            a1
+//      ---------------
+//      b1 +     a2
+//           ----------
+//           b2 +   a3
+//                -----
+//                b3 + ...
+//
+// Note that the first a1 and b1 returned by generator Gen are both used.
+//
+template <class Gen, class U>
+inline typename detail::fraction_traits<Gen>::result_type continued_fraction_a(Gen& g, const U& factor, boost::uintmax_t& max_terms)
+   BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits<Gen>::result_type) && noexcept(std::declval<Gen>()()))
+{
+   BOOST_MATH_STD_USING // ADL of std names
+
+   typedef detail::fraction_traits<Gen> traits;
+   typedef typename traits::result_type result_type;
+   typedef typename traits::value_type value_type;
+   typedef typename integer_scalar_type<result_type>::type integer_type;
+   typedef typename scalar_type<result_type>::type scalar_type;
+
+   integer_type const zero(0), one(1);
+
+   result_type tiny = detail::tiny_value<result_type>::get();
+   scalar_type terminator = abs(factor);
+
+   value_type v = g();
+
+   result_type f, C, D, delta, a0;
+   f = traits::b(v);
+   a0 = traits::a(v);
+   if(f == zero)
+      f = tiny;
+   C = f;
+   D = 0;
+
+   boost::uintmax_t counter(max_terms);
+
+   do{
+      v = g();
+      D = traits::b(v) + traits::a(v) * D;
+      if(D == zero)
+         D = tiny;
+      C = traits::b(v) + traits::a(v) / C;
+      if(C == zero)
+         C = tiny;
+      D = one/D;
+      delta = C*D;
+      f = f * delta;
+   }while((abs(delta - one) > terminator) && --counter);
+
+   max_terms = max_terms - counter;
+
+   return a0/f;
+}
+
+template <class Gen, class U>
+inline typename detail::fraction_traits<Gen>::result_type continued_fraction_a(Gen& g, const U& factor)
+   BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits<Gen>::result_type) && noexcept(std::declval<Gen>()()))
+{
+   boost::uintmax_t max_iter = (std::numeric_limits<boost::uintmax_t>::max)();
+   return continued_fraction_a(g, factor, max_iter);
+}
+
+template <class Gen>
+inline typename detail::fraction_traits<Gen>::result_type continued_fraction_a(Gen& g, int bits)
+   BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits<Gen>::result_type) && noexcept(std::declval<Gen>()()))
+{
+   BOOST_MATH_STD_USING // ADL of std names
+
+   typedef detail::fraction_traits<Gen> traits;
+   typedef typename traits::result_type result_type;
+
+   result_type factor = ldexp(1.0f, 1-bits); // 1 / pow(result_type(2), bits);
+   boost::uintmax_t max_iter = (std::numeric_limits<boost::uintmax_t>::max)();
+
+   return continued_fraction_a(g, factor, max_iter);
+}
+
+template <class Gen>
+inline typename detail::fraction_traits<Gen>::result_type continued_fraction_a(Gen& g, int bits, boost::uintmax_t& max_terms)
+   BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits<Gen>::result_type) && noexcept(std::declval<Gen>()()))
+{
+   BOOST_MATH_STD_USING // ADL of std names
+
+   typedef detail::fraction_traits<Gen> traits;
+   typedef typename traits::result_type result_type;
+
+   result_type factor = ldexp(1.0f, 1-bits); // 1 / pow(result_type(2), bits);
+   return continued_fraction_a(g, factor, max_terms);
+}
+
+} // namespace tools
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_TOOLS_FRACTION_INCLUDED
+
diff --git a/ThirdParty/boost/math/tools/precision.hpp b/ThirdParty/boost/math/tools/precision.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..73757295d219ec4f5e114ce7ea2892f11bad06f9
--- /dev/null
+++ b/ThirdParty/boost/math/tools/precision.hpp
@@ -0,0 +1,409 @@
+//  Copyright John Maddock 2005-2006.
+//  Use, modification and distribution are subject to 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_TOOLS_PRECISION_INCLUDED
+#define BOOST_MATH_TOOLS_PRECISION_INCLUDED
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/limits.hpp>
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/math/policies/policy.hpp>
+
+// These two are for LDBL_MAN_DIG:
+#include <limits.h>
+#include <math.h>
+
+namespace boost{ namespace math
+{
+namespace tools
+{
+// If T is not specialized, the functions digits, max_value and min_value,
+// all get synthesised automatically from std::numeric_limits.
+// However, if numeric_limits is not specialised for type RealType,
+// for example with NTL::RR type, then you will get a compiler error
+// when code tries to use these functions, unless you explicitly specialise them.
+
+// For example if the precision of RealType varies at runtime,
+// then numeric_limits support may not be appropriate,
+// see boost/math/tools/ntl.hpp  for examples like
+// template <> NTL::RR max_value<NTL::RR> ...
+// See  Conceptual Requirements for Real Number Types.
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) BOOST_NOEXCEPT
+{
+#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+   BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::is_specialized);
+   BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::radix == 2 || ::std::numeric_limits<T>::radix == 10);
+#else
+   BOOST_ASSERT(::std::numeric_limits<T>::is_specialized);
+   BOOST_ASSERT(::std::numeric_limits<T>::radix == 2 || ::std::numeric_limits<T>::radix == 10);
+#endif
+   return std::numeric_limits<T>::radix == 2 
+      ? std::numeric_limits<T>::digits
+      : ((std::numeric_limits<T>::digits + 1) * 1000L) / 301L;
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T))  BOOST_MATH_NOEXCEPT(T)
+{
+#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+   BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::is_specialized);
+#else
+   BOOST_ASSERT(::std::numeric_limits<T>::is_specialized);
+#endif
+   return (std::numeric_limits<T>::max)();
+} // Also used as a finite 'infinite' value for - and +infinity, for example:
+// -max_value<double> = -1.79769e+308, max_value<double> = 1.79769e+308.
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T)
+{
+#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+   BOOST_STATIC_ASSERT( ::std::numeric_limits<T>::is_specialized);
+#else
+   BOOST_ASSERT(::std::numeric_limits<T>::is_specialized);
+#endif
+   return (std::numeric_limits<T>::min)();
+}
+
+namespace detail{
+//
+// Logarithmic limits come next, note that although
+// we can compute these from the log of the max value
+// that is not in general thread safe (if we cache the value)
+// so it's better to specialise these:
+//
+// For type float first:
+//
+template <class T>
+inline BOOST_MATH_CONSTEXPR T log_max_value(const boost::integral_constant<int, 128>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T)
+{
+   return 88.0f;
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T log_min_value(const boost::integral_constant<int, 128>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T)
+{
+   return -87.0f;
+}
+//
+// Now double:
+//
+template <class T>
+inline BOOST_MATH_CONSTEXPR T log_max_value(const boost::integral_constant<int, 1024>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T)
+{
+   return 709.0;
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T log_min_value(const boost::integral_constant<int, 1024>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T)
+{
+   return -708.0;
+}
+//
+// 80 and 128-bit long doubles:
+//
+template <class T>
+inline BOOST_MATH_CONSTEXPR T log_max_value(const boost::integral_constant<int, 16384>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T)
+{
+   return 11356.0L;
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T log_min_value(const boost::integral_constant<int, 16384>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T)
+{
+   return -11355.0L;
+}
+
+template <class T>
+inline T log_max_value(const boost::integral_constant<int, 0>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))
+{
+   BOOST_MATH_STD_USING
+#ifdef __SUNPRO_CC
+   static const T m = boost::math::tools::max_value<T>();
+   static const T val = log(m);
+#else
+   static const T val = log(boost::math::tools::max_value<T>());
+#endif
+   return val;
+}
+
+template <class T>
+inline T log_min_value(const boost::integral_constant<int, 0>& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))
+{
+   BOOST_MATH_STD_USING
+#ifdef __SUNPRO_CC
+   static const T m = boost::math::tools::min_value<T>();
+   static const T val = log(m);
+#else
+   static const T val = log(boost::math::tools::min_value<T>());
+#endif
+   return val;
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T epsilon(const boost::true_type& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_MATH_NOEXCEPT(T)
+{
+   return std::numeric_limits<T>::epsilon();
+}
+
+#if defined(__GNUC__) && ((LDBL_MANT_DIG == 106) || (__LDBL_MANT_DIG__ == 106))
+template <>
+inline BOOST_MATH_CONSTEXPR long double epsilon<long double>(const boost::true_type& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(long double)) BOOST_MATH_NOEXCEPT(long double)
+{
+   // numeric_limits on Darwin (and elsewhere) tells lies here:
+   // the issue is that long double on a few platforms is
+   // really a "double double" which has a non-contiguous
+   // mantissa: 53 bits followed by an unspecified number of
+   // zero bits, followed by 53 more bits.  Thus the apparent
+   // precision of the type varies depending where it's been.
+   // Set epsilon to the value that a 106 bit fixed mantissa
+   // type would have, as that will give us sensible behaviour everywhere.
+   //
+   // This static assert fails for some unknown reason, so
+   // disabled for now...
+   // BOOST_STATIC_ASSERT(std::numeric_limits<long double>::digits == 106);
+   return 2.4651903288156618919116517665087e-32L;
+}
+#endif
+
+template <class T>
+inline T epsilon(const boost::false_type& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T))
+{
+   // Note: don't cache result as precision may vary at runtime:
+   BOOST_MATH_STD_USING  // for ADL of std names
+   return ldexp(static_cast<T>(1), 1-policies::digits<T, policies::policy<> >());
+}
+
+template <class T>
+struct log_limit_traits
+{
+   typedef typename mpl::if_c<
+      (std::numeric_limits<T>::radix == 2) &&
+      (std::numeric_limits<T>::max_exponent == 128
+         || std::numeric_limits<T>::max_exponent == 1024
+         || std::numeric_limits<T>::max_exponent == 16384),
+      boost::integral_constant<int, (std::numeric_limits<T>::max_exponent > INT_MAX ? INT_MAX : static_cast<int>(std::numeric_limits<T>::max_exponent))>,
+      boost::integral_constant<int, 0>
+   >::type tag_type;
+   BOOST_STATIC_CONSTANT(bool, value = tag_type::value ? true : false);
+   BOOST_STATIC_ASSERT(::std::numeric_limits<T>::is_specialized || (value == 0));
+};
+
+template <class T, bool b> struct log_limit_noexcept_traits_imp : public log_limit_traits<T> {};
+template <class T> struct log_limit_noexcept_traits_imp<T, false> : public boost::integral_constant<bool, false> {};
+
+template <class T>
+struct log_limit_noexcept_traits : public log_limit_noexcept_traits_imp<T, BOOST_MATH_IS_FLOAT(T)> {};
+
+} // namespace detail
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4309)
+#endif
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T log_max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_NOEXCEPT_IF(detail::log_limit_noexcept_traits<T>::value)
+{
+#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+   return detail::log_max_value<T>(typename detail::log_limit_traits<T>::tag_type());
+#else
+   BOOST_ASSERT(::std::numeric_limits<T>::is_specialized);
+   BOOST_MATH_STD_USING
+   static const T val = log((std::numeric_limits<T>::max)());
+   return val;
+#endif
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T log_min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) BOOST_NOEXCEPT_IF(detail::log_limit_noexcept_traits<T>::value)
+{
+#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+   return detail::log_min_value<T>(typename detail::log_limit_traits<T>::tag_type());
+#else
+   BOOST_ASSERT(::std::numeric_limits<T>::is_specialized);
+   BOOST_MATH_STD_USING
+   static const T val = log((std::numeric_limits<T>::min)());
+   return val;
+#endif
+}
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) BOOST_MATH_NOEXCEPT(T)
+{
+#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+   return detail::epsilon<T>(boost::integral_constant<bool, ::std::numeric_limits<T>::is_specialized>());
+#else
+   return ::std::numeric_limits<T>::is_specialized ?
+      detail::epsilon<T>(boost::true_type()) :
+      detail::epsilon<T>(boost::false_type());
+#endif
+}
+
+namespace detail{
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T root_epsilon_imp(const boost::integral_constant<int, 24>&) BOOST_MATH_NOEXCEPT(T)
+{
+   return static_cast<T>(0.00034526698300124390839884978618400831996329879769945L);
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T root_epsilon_imp(const T*, const boost::integral_constant<int, 53>&) BOOST_MATH_NOEXCEPT(T)
+{
+   return static_cast<T>(0.1490116119384765625e-7L);
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T root_epsilon_imp(const T*, const boost::integral_constant<int, 64>&) BOOST_MATH_NOEXCEPT(T)
+{
+   return static_cast<T>(0.32927225399135962333569506281281311031656150598474e-9L);
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T root_epsilon_imp(const T*, const boost::integral_constant<int, 113>&) BOOST_MATH_NOEXCEPT(T)
+{
+   return static_cast<T>(0.1387778780781445675529539585113525390625e-16L);
+}
+
+template <class T, class Tag>
+inline T root_epsilon_imp(const T*, const Tag&)
+{
+   BOOST_MATH_STD_USING
+   static const T r_eps = sqrt(tools::epsilon<T>());
+   return r_eps;
+}
+
+template <class T>
+inline T root_epsilon_imp(const T*, const boost::integral_constant<int, 0>&)
+{
+   BOOST_MATH_STD_USING
+   return sqrt(tools::epsilon<T>());
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T cbrt_epsilon_imp(const boost::integral_constant<int, 24>&) BOOST_MATH_NOEXCEPT(T)
+{
+   return static_cast<T>(0.0049215666011518482998719164346805794944150447839903L);
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T cbrt_epsilon_imp(const T*, const boost::integral_constant<int, 53>&) BOOST_MATH_NOEXCEPT(T)
+{
+   return static_cast<T>(6.05545445239333906078989272793696693569753008995e-6L);
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T cbrt_epsilon_imp(const T*, const boost::integral_constant<int, 64>&) BOOST_MATH_NOEXCEPT(T)
+{
+   return static_cast<T>(4.76837158203125e-7L);
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T cbrt_epsilon_imp(const T*, const boost::integral_constant<int, 113>&) BOOST_MATH_NOEXCEPT(T)
+{
+   return static_cast<T>(5.7749313854154005630396773604745549542403508090496e-12L);
+}
+
+template <class T, class Tag>
+inline T cbrt_epsilon_imp(const T*, const Tag&)
+{
+   BOOST_MATH_STD_USING;
+   static const T cbrt_eps = pow(tools::epsilon<T>(), T(1) / 3);
+   return cbrt_eps;
+}
+
+template <class T>
+inline T cbrt_epsilon_imp(const T*, const boost::integral_constant<int, 0>&)
+{
+   BOOST_MATH_STD_USING;
+   return pow(tools::epsilon<T>(), T(1) / 3);
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T forth_root_epsilon_imp(const T*, const boost::integral_constant<int, 24>&) BOOST_MATH_NOEXCEPT(T)
+{
+   return static_cast<T>(0.018581361171917516667460937040007436176452688944747L);
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T forth_root_epsilon_imp(const T*, const boost::integral_constant<int, 53>&) BOOST_MATH_NOEXCEPT(T)
+{
+   return static_cast<T>(0.0001220703125L);
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T forth_root_epsilon_imp(const T*, const boost::integral_constant<int, 64>&) BOOST_MATH_NOEXCEPT(T)
+{
+   return static_cast<T>(0.18145860519450699870567321328132261891067079047605e-4L);
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T forth_root_epsilon_imp(const T*, const boost::integral_constant<int, 113>&) BOOST_MATH_NOEXCEPT(T)
+{
+   return static_cast<T>(0.37252902984619140625e-8L);
+}
+
+template <class T, class Tag>
+inline T forth_root_epsilon_imp(const T*, const Tag&)
+{
+   BOOST_MATH_STD_USING
+   static const T r_eps = sqrt(sqrt(tools::epsilon<T>()));
+   return r_eps;
+}
+
+template <class T>
+inline T forth_root_epsilon_imp(const T*, const boost::integral_constant<int, 0>&)
+{
+   BOOST_MATH_STD_USING
+   return sqrt(sqrt(tools::epsilon<T>()));
+}
+
+template <class T>
+struct root_epsilon_traits
+{
+   typedef boost::integral_constant<int, (::std::numeric_limits<T>::radix == 2) && (::std::numeric_limits<T>::digits != INT_MAX) ? std::numeric_limits<T>::digits : 0> tag_type;
+   BOOST_STATIC_CONSTANT(bool, has_noexcept = (tag_type::value == 113) || (tag_type::value == 64) || (tag_type::value == 53) || (tag_type::value == 24));
+};
+
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T root_epsilon() BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(T) && detail::root_epsilon_traits<T>::has_noexcept)
+{
+   return detail::root_epsilon_imp(static_cast<T const*>(0), typename detail::root_epsilon_traits<T>::tag_type());
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T cbrt_epsilon() BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(T) && detail::root_epsilon_traits<T>::has_noexcept)
+{
+   return detail::cbrt_epsilon_imp(static_cast<T const*>(0), typename detail::root_epsilon_traits<T>::tag_type());
+}
+
+template <class T>
+inline BOOST_MATH_CONSTEXPR T forth_root_epsilon() BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(T) && detail::root_epsilon_traits<T>::has_noexcept)
+{
+   return detail::forth_root_epsilon_imp(static_cast<T const*>(0), typename detail::root_epsilon_traits<T>::tag_type());
+}
+
+} // namespace tools
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_TOOLS_PRECISION_INCLUDED
+
diff --git a/ThirdParty/boost/math/tools/rational.hpp b/ThirdParty/boost/math/tools/rational.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..940e8ca3c39a966b44e9d66ecdbd991484059394
--- /dev/null
+++ b/ThirdParty/boost/math/tools/rational.hpp
@@ -0,0 +1,333 @@
+//  (C) Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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_TOOLS_RATIONAL_HPP
+#define BOOST_MATH_TOOLS_RATIONAL_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/array.hpp>
+#include <boost/math/tools/config.hpp>
+#include <boost/mpl/int.hpp>
+
+#if BOOST_MATH_POLY_METHOD == 1
+#  define BOOST_HEADER() <BOOST_JOIN(boost/math/tools/detail/polynomial_horner1_, BOOST_MATH_MAX_POLY_ORDER).hpp>
+#  include BOOST_HEADER()
+#  undef BOOST_HEADER
+#elif BOOST_MATH_POLY_METHOD == 2
+#  define BOOST_HEADER() <BOOST_JOIN(boost/math/tools/detail/polynomial_horner2_, BOOST_MATH_MAX_POLY_ORDER).hpp>
+#  include BOOST_HEADER()
+#  undef BOOST_HEADER
+#elif BOOST_MATH_POLY_METHOD == 3
+#  define BOOST_HEADER() <BOOST_JOIN(boost/math/tools/detail/polynomial_horner3_, BOOST_MATH_MAX_POLY_ORDER).hpp>
+#  include BOOST_HEADER()
+#  undef BOOST_HEADER
+#endif
+#if BOOST_MATH_RATIONAL_METHOD == 1
+#  define BOOST_HEADER() <BOOST_JOIN(boost/math/tools/detail/rational_horner1_, BOOST_MATH_MAX_POLY_ORDER).hpp>
+#  include BOOST_HEADER()
+#  undef BOOST_HEADER
+#elif BOOST_MATH_RATIONAL_METHOD == 2
+#  define BOOST_HEADER() <BOOST_JOIN(boost/math/tools/detail/rational_horner2_, BOOST_MATH_MAX_POLY_ORDER).hpp>
+#  include BOOST_HEADER()
+#  undef BOOST_HEADER
+#elif BOOST_MATH_RATIONAL_METHOD == 3
+#  define BOOST_HEADER() <BOOST_JOIN(boost/math/tools/detail/rational_horner3_, BOOST_MATH_MAX_POLY_ORDER).hpp>
+#  include BOOST_HEADER()
+#  undef BOOST_HEADER
+#endif
+
+#if 0
+//
+// This just allows dependency trackers to find the headers
+// used in the above PP-magic.
+//
+#include <boost/math/tools/detail/polynomial_horner1_2.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_3.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_4.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_5.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_6.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_7.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_8.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_9.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_10.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_11.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_12.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_13.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_14.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_15.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_16.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_17.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_18.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_19.hpp>
+#include <boost/math/tools/detail/polynomial_horner1_20.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_2.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_3.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_4.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_5.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_6.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_7.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_8.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_9.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_10.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_11.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_12.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_13.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_14.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_15.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_16.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_17.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_18.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_19.hpp>
+#include <boost/math/tools/detail/polynomial_horner2_20.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_2.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_3.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_4.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_5.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_6.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_7.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_8.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_9.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_10.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_11.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_12.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_13.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_14.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_15.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_16.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_17.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_18.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_19.hpp>
+#include <boost/math/tools/detail/polynomial_horner3_20.hpp>
+#include <boost/math/tools/detail/rational_horner1_2.hpp>
+#include <boost/math/tools/detail/rational_horner1_3.hpp>
+#include <boost/math/tools/detail/rational_horner1_4.hpp>
+#include <boost/math/tools/detail/rational_horner1_5.hpp>
+#include <boost/math/tools/detail/rational_horner1_6.hpp>
+#include <boost/math/tools/detail/rational_horner1_7.hpp>
+#include <boost/math/tools/detail/rational_horner1_8.hpp>
+#include <boost/math/tools/detail/rational_horner1_9.hpp>
+#include <boost/math/tools/detail/rational_horner1_10.hpp>
+#include <boost/math/tools/detail/rational_horner1_11.hpp>
+#include <boost/math/tools/detail/rational_horner1_12.hpp>
+#include <boost/math/tools/detail/rational_horner1_13.hpp>
+#include <boost/math/tools/detail/rational_horner1_14.hpp>
+#include <boost/math/tools/detail/rational_horner1_15.hpp>
+#include <boost/math/tools/detail/rational_horner1_16.hpp>
+#include <boost/math/tools/detail/rational_horner1_17.hpp>
+#include <boost/math/tools/detail/rational_horner1_18.hpp>
+#include <boost/math/tools/detail/rational_horner1_19.hpp>
+#include <boost/math/tools/detail/rational_horner1_20.hpp>
+#include <boost/math/tools/detail/rational_horner2_2.hpp>
+#include <boost/math/tools/detail/rational_horner2_3.hpp>
+#include <boost/math/tools/detail/rational_horner2_4.hpp>
+#include <boost/math/tools/detail/rational_horner2_5.hpp>
+#include <boost/math/tools/detail/rational_horner2_6.hpp>
+#include <boost/math/tools/detail/rational_horner2_7.hpp>
+#include <boost/math/tools/detail/rational_horner2_8.hpp>
+#include <boost/math/tools/detail/rational_horner2_9.hpp>
+#include <boost/math/tools/detail/rational_horner2_10.hpp>
+#include <boost/math/tools/detail/rational_horner2_11.hpp>
+#include <boost/math/tools/detail/rational_horner2_12.hpp>
+#include <boost/math/tools/detail/rational_horner2_13.hpp>
+#include <boost/math/tools/detail/rational_horner2_14.hpp>
+#include <boost/math/tools/detail/rational_horner2_15.hpp>
+#include <boost/math/tools/detail/rational_horner2_16.hpp>
+#include <boost/math/tools/detail/rational_horner2_17.hpp>
+#include <boost/math/tools/detail/rational_horner2_18.hpp>
+#include <boost/math/tools/detail/rational_horner2_19.hpp>
+#include <boost/math/tools/detail/rational_horner2_20.hpp>
+#include <boost/math/tools/detail/rational_horner3_2.hpp>
+#include <boost/math/tools/detail/rational_horner3_3.hpp>
+#include <boost/math/tools/detail/rational_horner3_4.hpp>
+#include <boost/math/tools/detail/rational_horner3_5.hpp>
+#include <boost/math/tools/detail/rational_horner3_6.hpp>
+#include <boost/math/tools/detail/rational_horner3_7.hpp>
+#include <boost/math/tools/detail/rational_horner3_8.hpp>
+#include <boost/math/tools/detail/rational_horner3_9.hpp>
+#include <boost/math/tools/detail/rational_horner3_10.hpp>
+#include <boost/math/tools/detail/rational_horner3_11.hpp>
+#include <boost/math/tools/detail/rational_horner3_12.hpp>
+#include <boost/math/tools/detail/rational_horner3_13.hpp>
+#include <boost/math/tools/detail/rational_horner3_14.hpp>
+#include <boost/math/tools/detail/rational_horner3_15.hpp>
+#include <boost/math/tools/detail/rational_horner3_16.hpp>
+#include <boost/math/tools/detail/rational_horner3_17.hpp>
+#include <boost/math/tools/detail/rational_horner3_18.hpp>
+#include <boost/math/tools/detail/rational_horner3_19.hpp>
+#include <boost/math/tools/detail/rational_horner3_20.hpp>
+#endif
+
+namespace boost{ namespace math{ namespace tools{
+
+//
+// Forward declaration to keep two phase lookup happy:
+//
+template <class T, class U>
+U evaluate_polynomial(const T* poly, U const& z, std::size_t count) BOOST_MATH_NOEXCEPT(U);
+
+namespace detail{
+
+template <class T, class V, class Tag>
+inline V evaluate_polynomial_c_imp(const T* a, const V& val, const Tag*) BOOST_MATH_NOEXCEPT(V)
+{
+   return evaluate_polynomial(a, val, Tag::value);
+}
+
+} // namespace detail
+
+//
+// Polynomial evaluation with runtime size.
+// This requires a for-loop which may be more expensive than
+// the loop expanded versions above:
+//
+template <class T, class U>
+inline U evaluate_polynomial(const T* poly, U const& z, std::size_t count) BOOST_MATH_NOEXCEPT(U)
+{
+   BOOST_ASSERT(count > 0);
+   U sum = static_cast<U>(poly[count - 1]);
+   for(int i = static_cast<int>(count) - 2; i >= 0; --i)
+   {
+      sum *= z;
+      sum += static_cast<U>(poly[i]);
+   }
+   return sum;
+}
+//
+// Compile time sized polynomials, just inline forwarders to the
+// implementations above:
+//
+template <std::size_t N, class T, class V>
+inline V evaluate_polynomial(const T(&a)[N], const V& val) BOOST_MATH_NOEXCEPT(V)
+{
+   typedef boost::integral_constant<int, N> tag_type;
+   return detail::evaluate_polynomial_c_imp(static_cast<const T*>(a), val, static_cast<tag_type const*>(0));
+}
+
+template <std::size_t N, class T, class V>
+inline V evaluate_polynomial(const boost::array<T,N>& a, const V& val) BOOST_MATH_NOEXCEPT(V)
+{
+   typedef boost::integral_constant<int, N> tag_type;
+   return detail::evaluate_polynomial_c_imp(static_cast<const T*>(a.data()), val, static_cast<tag_type const*>(0));
+}
+//
+// Even polynomials are trivial: just square the argument!
+//
+template <class T, class U>
+inline U evaluate_even_polynomial(const T* poly, U z, std::size_t count) BOOST_MATH_NOEXCEPT(U)
+{
+   return evaluate_polynomial(poly, U(z*z), count);
+}
+
+template <std::size_t N, class T, class V>
+inline V evaluate_even_polynomial(const T(&a)[N], const V& z) BOOST_MATH_NOEXCEPT(V)
+{
+   return evaluate_polynomial(a, V(z*z));
+}
+
+template <std::size_t N, class T, class V>
+inline V evaluate_even_polynomial(const boost::array<T,N>& a, const V& z) BOOST_MATH_NOEXCEPT(V)
+{
+   return evaluate_polynomial(a, V(z*z));
+}
+//
+// Odd polynomials come next:
+//
+template <class T, class U>
+inline U evaluate_odd_polynomial(const T* poly, U z, std::size_t count) BOOST_MATH_NOEXCEPT(U)
+{
+   return poly[0] + z * evaluate_polynomial(poly+1, U(z*z), count-1);
+}
+
+template <std::size_t N, class T, class V>
+inline V evaluate_odd_polynomial(const T(&a)[N], const V& z) BOOST_MATH_NOEXCEPT(V)
+{
+   typedef boost::integral_constant<int, N-1> tag_type;
+   return a[0] + z * detail::evaluate_polynomial_c_imp(static_cast<const T*>(a) + 1, V(z*z), static_cast<tag_type const*>(0));
+}
+
+template <std::size_t N, class T, class V>
+inline V evaluate_odd_polynomial(const boost::array<T,N>& a, const V& z) BOOST_MATH_NOEXCEPT(V)
+{
+   typedef boost::integral_constant<int, N-1> tag_type;
+   return a[0] + z * detail::evaluate_polynomial_c_imp(static_cast<const T*>(a.data()) + 1, V(z*z), static_cast<tag_type const*>(0));
+}
+
+template <class T, class U, class V>
+V evaluate_rational(const T* num, const U* denom, const V& z_, std::size_t count) BOOST_MATH_NOEXCEPT(V);
+
+namespace detail{
+
+template <class T, class U, class V, class Tag>
+inline V evaluate_rational_c_imp(const T* num, const U* denom, const V& z, const Tag*) BOOST_MATH_NOEXCEPT(V)
+{
+   return boost::math::tools::evaluate_rational(num, denom, z, Tag::value);
+}
+
+}
+//
+// Rational functions: numerator and denominator must be
+// equal in size.  These always have a for-loop and so may be less
+// efficient than evaluating a pair of polynomials. However, there
+// are some tricks we can use to prevent overflow that might otherwise
+// occur in polynomial evaluation, if z is large.  This is important
+// in our Lanczos code for example.
+//
+template <class T, class U, class V>
+V evaluate_rational(const T* num, const U* denom, const V& z_, std::size_t count) BOOST_MATH_NOEXCEPT(V)
+{
+   V z(z_);
+   V s1, s2;
+   if(z <= 1)
+   {
+      s1 = static_cast<V>(num[count-1]);
+      s2 = static_cast<V>(denom[count-1]);
+      for(int i = (int)count - 2; i >= 0; --i)
+      {
+         s1 *= z;
+         s2 *= z;
+         s1 += num[i];
+         s2 += denom[i];
+      }
+   }
+   else
+   {
+      z = 1 / z;
+      s1 = static_cast<V>(num[0]);
+      s2 = static_cast<V>(denom[0]);
+      for(unsigned i = 1; i < count; ++i)
+      {
+         s1 *= z;
+         s2 *= z;
+         s1 += num[i];
+         s2 += denom[i];
+      }
+   }
+   return s1 / s2;
+}
+
+template <std::size_t N, class T, class U, class V>
+inline V evaluate_rational(const T(&a)[N], const U(&b)[N], const V& z) BOOST_MATH_NOEXCEPT(V)
+{
+   return detail::evaluate_rational_c_imp(a, b, z, static_cast<const boost::integral_constant<int, N>*>(0));
+}
+
+template <std::size_t N, class T, class U, class V>
+inline V evaluate_rational(const boost::array<T,N>& a, const boost::array<U,N>& b, const V& z) BOOST_MATH_NOEXCEPT(V)
+{
+   return detail::evaluate_rational_c_imp(a.data(), b.data(), z, static_cast<boost::integral_constant<int, N>*>(0));
+}
+
+} // namespace tools
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_TOOLS_RATIONAL_HPP
+
+
+
+
diff --git a/ThirdParty/boost/math/tools/roots.hpp b/ThirdParty/boost/math/tools/roots.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..853334b04b98314e65b410445317eb6075d4c314
--- /dev/null
+++ b/ThirdParty/boost/math/tools/roots.hpp
@@ -0,0 +1,1015 @@
+//  (C) Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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_TOOLS_NEWTON_SOLVER_HPP
+#define BOOST_MATH_TOOLS_NEWTON_SOLVER_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+#include <boost/math/tools/complex.hpp> // test for multiprecision types.
+
+#include <iostream>
+#include <utility>
+#include <boost/config/no_tr1/cmath.hpp>
+#include <stdexcept>
+
+#include <boost/math/tools/config.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/assert.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/math/tools/cxx03_warn.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable: 4512)
+#endif
+#include <boost/math/tools/tuple.hpp>
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#include <boost/math/special_functions/sign.hpp>
+#include <boost/math/special_functions/next.hpp>
+#include <boost/math/tools/toms748_solve.hpp>
+#include <boost/math/policies/error_handling.hpp>
+
+namespace boost {
+namespace math {
+namespace tools {
+
+namespace detail {
+
+namespace dummy {
+
+   template<int n, class T>
+   typename T::value_type get(const T&) BOOST_MATH_NOEXCEPT(T);
+}
+
+template <class Tuple, class T>
+void unpack_tuple(const Tuple& t, T& a, T& b) BOOST_MATH_NOEXCEPT(T)
+{
+   using dummy::get;
+   // Use ADL to find the right overload for get:
+   a = get<0>(t);
+   b = get<1>(t);
+}
+template <class Tuple, class T>
+void unpack_tuple(const Tuple& t, T& a, T& b, T& c) BOOST_MATH_NOEXCEPT(T)
+{
+   using dummy::get;
+   // Use ADL to find the right overload for get:
+   a = get<0>(t);
+   b = get<1>(t);
+   c = get<2>(t);
+}
+
+template <class Tuple, class T>
+inline void unpack_0(const Tuple& t, T& val) BOOST_MATH_NOEXCEPT(T)
+{
+   using dummy::get;
+   // Rely on ADL to find the correct overload of get:
+   val = get<0>(t);
+}
+
+template <class T, class U, class V>
+inline void unpack_tuple(const std::pair<T, U>& p, V& a, V& b) BOOST_MATH_NOEXCEPT(T)
+{
+   a = p.first;
+   b = p.second;
+}
+template <class T, class U, class V>
+inline void unpack_0(const std::pair<T, U>& p, V& a) BOOST_MATH_NOEXCEPT(T)
+{
+   a = p.first;
+}
+
+template <class F, class T>
+void handle_zero_derivative(F f,
+   T& last_f0,
+   const T& f0,
+   T& delta,
+   T& result,
+   T& guess,
+   const T& min,
+   const T& max) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
+{
+   if (last_f0 == 0)
+   {
+      // this must be the first iteration, pretend that we had a
+      // previous one at either min or max:
+      if (result == min)
+      {
+         guess = max;
+      }
+      else
+      {
+         guess = min;
+      }
+      unpack_0(f(guess), last_f0);
+      delta = guess - result;
+   }
+   if (sign(last_f0) * sign(f0) < 0)
+   {
+      // we've crossed over so move in opposite direction to last step:
+      if (delta < 0)
+      {
+         delta = (result - min) / 2;
+      }
+      else
+      {
+         delta = (result - max) / 2;
+      }
+   }
+   else
+   {
+      // move in same direction as last step:
+      if (delta < 0)
+      {
+         delta = (result - max) / 2;
+      }
+      else
+      {
+         delta = (result - min) / 2;
+      }
+   }
+}
+
+} // namespace
+
+template <class F, class T, class Tol, class Policy>
+std::pair<T, T> bisect(F f, T min, T max, Tol tol, boost::uintmax_t& max_iter, const Policy& pol) BOOST_NOEXCEPT_IF(policies::is_noexcept_error_policy<Policy>::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
+{
+   T fmin = f(min);
+   T fmax = f(max);
+   if (fmin == 0)
+   {
+      max_iter = 2;
+      return std::make_pair(min, min);
+   }
+   if (fmax == 0)
+   {
+      max_iter = 2;
+      return std::make_pair(max, max);
+   }
+
+   //
+   // Error checking:
+   //
+   static const char* function = "boost::math::tools::bisect<%1%>";
+   if (min >= max)
+   {
+      return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function,
+         "Arguments in wrong order in boost::math::tools::bisect (first arg=%1%)", min, pol));
+   }
+   if (fmin * fmax >= 0)
+   {
+      return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function,
+         "No change of sign in boost::math::tools::bisect, either there is no root to find, or there are multiple roots in the interval (f(min) = %1%).", fmin, pol));
+   }
+
+   //
+   // Three function invocations so far:
+   //
+   boost::uintmax_t count = max_iter;
+   if (count < 3)
+      count = 0;
+   else
+      count -= 3;
+
+   while (count && (0 == tol(min, max)))
+   {
+      T mid = (min + max) / 2;
+      T fmid = f(mid);
+      if ((mid == max) || (mid == min))
+         break;
+      if (fmid == 0)
+      {
+         min = max = mid;
+         break;
+      }
+      else if (sign(fmid) * sign(fmin) < 0)
+      {
+         max = mid;
+      }
+      else
+      {
+         min = mid;
+         fmin = fmid;
+      }
+      --count;
+   }
+
+   max_iter -= count;
+
+#ifdef BOOST_MATH_INSTRUMENT
+   std::cout << "Bisection iteration, final count = " << max_iter << std::endl;
+
+   static boost::uintmax_t max_count = 0;
+   if (max_iter > max_count)
+   {
+      max_count = max_iter;
+      std::cout << "Maximum iterations: " << max_iter << std::endl;
+   }
+#endif
+
+   return std::make_pair(min, max);
+}
+
+template <class F, class T, class Tol>
+inline std::pair<T, T> bisect(F f, T min, T max, Tol tol, boost::uintmax_t& max_iter)  BOOST_NOEXCEPT_IF(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
+{
+   return bisect(f, min, max, tol, max_iter, policies::policy<>());
+}
+
+template <class F, class T, class Tol>
+inline std::pair<T, T> bisect(F f, T min, T max, Tol tol) BOOST_NOEXCEPT_IF(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
+{
+   boost::uintmax_t m = (std::numeric_limits<boost::uintmax_t>::max)();
+   return bisect(f, min, max, tol, m, policies::policy<>());
+}
+
+
+template <class F, class T>
+T newton_raphson_iterate(F f, T guess, T min, T max, int digits, boost::uintmax_t& max_iter) BOOST_NOEXCEPT_IF(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
+{
+   BOOST_MATH_STD_USING
+
+   static const char* function = "boost::math::tools::newton_raphson_iterate<%1%>";
+   if (min >= max)
+   {
+      return policies::raise_evaluation_error(function, "Range arguments in wrong order in boost::math::tools::newton_raphson_iterate(first arg=%1%)", min, boost::math::policies::policy<>());
+   }
+
+   T f0(0), f1, last_f0(0);
+   T result = guess;
+
+   T factor = static_cast<T>(ldexp(1.0, 1 - digits));
+   T delta = tools::max_value<T>();
+   T delta1 = tools::max_value<T>();
+   T delta2 = tools::max_value<T>();
+
+   //
+   // We use these to sanity check that we do actually bracket a root,
+   // we update these to the function value when we update the endpoints
+   // of the range.  Then, provided at some point we update both endpoints
+   // checking that max_range_f * min_range_f <= 0 verifies there is a root
+   // to be found somewhere.  Note that if there is no root, and we approach 
+   // a local minima, then the derivative will go to zero, and hence the next
+   // step will jump out of bounds (or at least past the minima), so this
+   // check *should* happen in pathological cases.
+   //
+   T max_range_f = 0;
+   T min_range_f = 0;
+
+   boost::uintmax_t count(max_iter);
+
+#ifdef BOOST_MATH_INSTRUMENT
+   std::cout << "Newton_raphson_iterate, guess = " << guess << ", min = " << min << ", max = " << max
+      << ", digits = " << digits << ", max_iter = " << max_iter << std::endl;
+#endif
+
+   do {
+      last_f0 = f0;
+      delta2 = delta1;
+      delta1 = delta;
+      detail::unpack_tuple(f(result), f0, f1);
+      --count;
+      if (0 == f0)
+         break;
+      if (f1 == 0)
+      {
+         // Oops zero derivative!!!
+#ifdef BOOST_MATH_INSTRUMENT
+         std::cout << "Newton iteration, zero derivative found!" << std::endl;
+#endif
+         detail::handle_zero_derivative(f, last_f0, f0, delta, result, guess, min, max);
+      }
+      else
+      {
+         delta = f0 / f1;
+      }
+#ifdef BOOST_MATH_INSTRUMENT
+      std::cout << "Newton iteration " << max_iter - count << ", delta = " << delta << std::endl;
+#endif
+      if (fabs(delta * 2) > fabs(delta2))
+      {
+         // Last two steps haven't converged.
+         T shift = (delta > 0) ? (result - min) / 2 : (result - max) / 2;
+         if ((result != 0) && (fabs(shift) > fabs(result)))
+         {
+            delta = sign(delta) * fabs(result) * 1.1f; // Protect against huge jumps!
+            //delta = sign(delta) * result; // Protect against huge jumps! Failed for negative result. https://github.com/boostorg/math/issues/216
+         }
+         else
+            delta = shift;
+         // reset delta1/2 so we don't take this branch next time round:
+         delta1 = 3 * delta;
+         delta2 = 3 * delta;
+      }
+      guess = result;
+      result -= delta;
+      if (result <= min)
+      {
+         delta = 0.5F * (guess - min);
+         result = guess - delta;
+         if ((result == min) || (result == max))
+            break;
+      }
+      else if (result >= max)
+      {
+         delta = 0.5F * (guess - max);
+         result = guess - delta;
+         if ((result == min) || (result == max))
+            break;
+      }
+      // Update brackets:
+      if (delta > 0)
+      {
+         max = guess;
+         max_range_f = f0;
+      }
+      else
+      {
+         min = guess;
+         min_range_f = f0;
+      }
+      //
+      // Sanity check that we bracket the root:
+      //
+      if (max_range_f * min_range_f > 0)
+      {
+         return policies::raise_evaluation_error(function, "There appears to be no root to be found in boost::math::tools::newton_raphson_iterate, perhaps we have a local minima near current best guess of %1%", guess, boost::math::policies::policy<>());
+      }
+   }while(count && (fabs(result * factor) < fabs(delta)));
+
+   max_iter -= count;
+
+#ifdef BOOST_MATH_INSTRUMENT
+   std::cout << "Newton Raphson final iteration count = " << max_iter << std::endl;
+
+   static boost::uintmax_t max_count = 0;
+   if (max_iter > max_count)
+   {
+      max_count = max_iter;
+      // std::cout << "Maximum iterations: " << max_iter << std::endl;
+      // Puzzled what this tells us, so commented out for now?
+   }
+#endif
+
+   return result;
+}
+
+template <class F, class T>
+inline T newton_raphson_iterate(F f, T guess, T min, T max, int digits) BOOST_NOEXCEPT_IF(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
+{
+   boost::uintmax_t m = (std::numeric_limits<boost::uintmax_t>::max)();
+   return newton_raphson_iterate(f, guess, min, max, digits, m);
+}
+
+namespace detail {
+
+   struct halley_step
+   {
+      template <class T>
+      static T step(const T& /*x*/, const T& f0, const T& f1, const T& f2) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(T))
+      {
+         using std::fabs;
+         T denom = 2 * f0;
+         T num = 2 * f1 - f0 * (f2 / f1);
+         T delta;
+
+         BOOST_MATH_INSTRUMENT_VARIABLE(denom);
+         BOOST_MATH_INSTRUMENT_VARIABLE(num);
+
+         if ((fabs(num) < 1) && (fabs(denom) >= fabs(num) * tools::max_value<T>()))
+         {
+            // possible overflow, use Newton step:
+            delta = f0 / f1;
+         }
+         else
+            delta = denom / num;
+         return delta;
+      }
+   };
+
+   template <class F, class T>
+   T bracket_root_towards_min(F f, T guess, const T& f0, T& min, T& max, boost::uintmax_t& count) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())));
+
+   template <class F, class T>
+   T bracket_root_towards_max(F f, T guess, const T& f0, T& min, T& max, boost::uintmax_t& count) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
+   {
+      using std::fabs;
+      //
+      // Move guess towards max until we bracket the root, updating min and max as we go:
+      //
+      T guess0 = guess;
+      T multiplier = 2;
+      T f_current = f0;
+      if (fabs(min) < fabs(max))
+      {
+         while (--count && ((f_current < 0) == (f0 < 0)))
+         {
+            min = guess;
+            guess *= multiplier;
+            if (guess > max)
+            {
+               guess = max;
+               f_current = -f_current;  // There must be a change of sign!
+               break;
+            }
+            multiplier *= 2;
+            unpack_0(f(guess), f_current);
+         }
+      }
+      else
+      {
+         //
+         // If min and max are negative we have to divide to head towards max:
+         //
+         while (--count && ((f_current < 0) == (f0 < 0)))
+         {
+            min = guess;
+            guess /= multiplier;
+            if (guess > max)
+            {
+               guess = max;
+               f_current = -f_current;  // There must be a change of sign!
+               break;
+            }
+            multiplier *= 2;
+            unpack_0(f(guess), f_current);
+         }
+      }
+
+      if (count)
+      {
+         max = guess;
+         if (multiplier > 16)
+            return (guess0 - guess) + bracket_root_towards_min(f, guess, f_current, min, max, count);
+      }
+      return guess0 - (max + min) / 2;
+   }
+
+   template <class F, class T>
+   T bracket_root_towards_min(F f, T guess, const T& f0, T& min, T& max, boost::uintmax_t& count) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
+   {
+      using std::fabs;
+      //
+      // Move guess towards min until we bracket the root, updating min and max as we go:
+      //
+      T guess0 = guess;
+      T multiplier = 2;
+      T f_current = f0;
+
+      if (fabs(min) < fabs(max))
+      {
+         while (--count && ((f_current < 0) == (f0 < 0)))
+         {
+            max = guess;
+            guess /= multiplier;
+            if (guess < min)
+            {
+               guess = min;
+               f_current = -f_current;  // There must be a change of sign!
+               break;
+            }
+            multiplier *= 2;
+            unpack_0(f(guess), f_current);
+         }
+      }
+      else
+      {
+         //
+         // If min and max are negative we have to multiply to head towards min:
+         //
+         while (--count && ((f_current < 0) == (f0 < 0)))
+         {
+            max = guess;
+            guess *= multiplier;
+            if (guess < min)
+            {
+               guess = min;
+               f_current = -f_current;  // There must be a change of sign!
+               break;
+            }
+            multiplier *= 2;
+            unpack_0(f(guess), f_current);
+         }
+      }
+
+      if (count)
+      {
+         min = guess;
+         if (multiplier > 16)
+            return (guess0 - guess) + bracket_root_towards_max(f, guess, f_current, min, max, count);
+      }
+      return guess0 - (max + min) / 2;
+   }
+
+   template <class Stepper, class F, class T>
+   T second_order_root_finder(F f, T guess, T min, T max, int digits, boost::uintmax_t& max_iter) BOOST_NOEXCEPT_IF(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
+   {
+      BOOST_MATH_STD_USING
+
+#ifdef BOOST_MATH_INSTRUMENT
+        std::cout << "Second order root iteration, guess = " << guess << ", min = " << min << ", max = " << max
+        << ", digits = " << digits << ", max_iter = " << max_iter << std::endl;
+#endif
+      static const char* function = "boost::math::tools::halley_iterate<%1%>";
+      if (min >= max)
+      {
+         return policies::raise_evaluation_error(function, "Range arguments in wrong order in boost::math::tools::halley_iterate(first arg=%1%)", min, boost::math::policies::policy<>());
+      }
+
+      T f0(0), f1, f2;
+      T result = guess;
+
+      T factor = ldexp(static_cast<T>(1.0), 1 - digits);
+      T delta = (std::max)(T(10000000 * guess), T(10000000));  // arbitrarily large delta
+      T last_f0 = 0;
+      T delta1 = delta;
+      T delta2 = delta;
+      bool out_of_bounds_sentry = false;
+
+   #ifdef BOOST_MATH_INSTRUMENT
+      std::cout << "Second order root iteration, limit = " << factor << std::endl;
+   #endif
+
+      //
+      // We use these to sanity check that we do actually bracket a root,
+      // we update these to the function value when we update the endpoints
+      // of the range.  Then, provided at some point we update both endpoints
+      // checking that max_range_f * min_range_f <= 0 verifies there is a root
+      // to be found somewhere.  Note that if there is no root, and we approach 
+      // a local minima, then the derivative will go to zero, and hence the next
+      // step will jump out of bounds (or at least past the minima), so this
+      // check *should* happen in pathological cases.
+      //
+      T max_range_f = 0;
+      T min_range_f = 0;
+
+      boost::uintmax_t count(max_iter);
+
+      do {
+         last_f0 = f0;
+         delta2 = delta1;
+         delta1 = delta;
+         detail::unpack_tuple(f(result), f0, f1, f2);
+         --count;
+
+         BOOST_MATH_INSTRUMENT_VARIABLE(f0);
+         BOOST_MATH_INSTRUMENT_VARIABLE(f1);
+         BOOST_MATH_INSTRUMENT_VARIABLE(f2);
+
+         if (0 == f0)
+            break;
+         if (f1 == 0)
+         {
+            // Oops zero derivative!!!
+   #ifdef BOOST_MATH_INSTRUMENT
+            std::cout << "Second order root iteration, zero derivative found!" << std::endl;
+   #endif
+            detail::handle_zero_derivative(f, last_f0, f0, delta, result, guess, min, max);
+         }
+         else
+         {
+            if (f2 != 0)
+            {
+               delta = Stepper::step(result, f0, f1, f2);
+               if (delta * f1 / f0 < 0)
+               {
+                  // Oh dear, we have a problem as Newton and Halley steps
+                  // disagree about which way we should move.  Probably
+                  // there is cancelation error in the calculation of the
+                  // Halley step, or else the derivatives are so small
+                  // that their values are basically trash.  We will move
+                  // in the direction indicated by a Newton step, but
+                  // by no more than twice the current guess value, otherwise
+                  // we can jump way out of bounds if we're not careful.
+                  // See https://svn.boost.org/trac/boost/ticket/8314.
+                  delta = f0 / f1;
+                  if (fabs(delta) > 2 * fabs(guess))
+                     delta = (delta < 0 ? -1 : 1) * 2 * fabs(guess);
+               }
+            }
+            else
+               delta = f0 / f1;
+         }
+   #ifdef BOOST_MATH_INSTRUMENT
+         std::cout << "Second order root iteration, delta = " << delta << std::endl;
+   #endif
+         T convergence = fabs(delta / delta2);
+         if ((convergence > 0.8) && (convergence < 2))
+         {
+            // last two steps haven't converged.
+            delta = (delta > 0) ? (result - min) / 2 : (result - max) / 2;
+            if ((result != 0) && (fabs(delta) > result))
+               delta = sign(delta) * fabs(result) * 0.9f; // protect against huge jumps!
+            // reset delta2 so that this branch will *not* be taken on the
+            // next iteration:
+            delta2 = delta * 3;
+            delta1 = delta * 3;
+            BOOST_MATH_INSTRUMENT_VARIABLE(delta);
+         }
+         guess = result;
+         result -= delta;
+         BOOST_MATH_INSTRUMENT_VARIABLE(result);
+
+         // check for out of bounds step:
+         if (result < min)
+         {
+            T diff = ((fabs(min) < 1) && (fabs(result) > 1) && (tools::max_value<T>() / fabs(result) < fabs(min)))
+               ? T(1000)
+               : (fabs(min) < 1) && (fabs(tools::max_value<T>() * min) < fabs(result))
+               ? ((min < 0) != (result < 0)) ? -tools::max_value<T>() : tools::max_value<T>() : T(result / min);
+            if (fabs(diff) < 1)
+               diff = 1 / diff;
+            if (!out_of_bounds_sentry && (diff > 0) && (diff < 3))
+            {
+               // Only a small out of bounds step, lets assume that the result
+               // is probably approximately at min:
+               delta = 0.99f * (guess - min);
+               result = guess - delta;
+               out_of_bounds_sentry = true; // only take this branch once!
+            }
+            else
+            {
+               if (fabs(float_distance(min, max)) < 2)
+               {
+                  result = guess = (min + max) / 2;
+                  break;
+               }
+               delta = bracket_root_towards_min(f, guess, f0, min, max, count);
+               result = guess - delta;
+               guess = min;
+               continue;
+            }
+         }
+         else if (result > max)
+         {
+            T diff = ((fabs(max) < 1) && (fabs(result) > 1) && (tools::max_value<T>() / fabs(result) < fabs(max))) ? T(1000) : T(result / max);
+            if (fabs(diff) < 1)
+               diff = 1 / diff;
+            if (!out_of_bounds_sentry && (diff > 0) && (diff < 3))
+            {
+               // Only a small out of bounds step, lets assume that the result
+               // is probably approximately at min:
+               delta = 0.99f * (guess - max);
+               result = guess - delta;
+               out_of_bounds_sentry = true; // only take this branch once!
+            }
+            else
+            {
+               if (fabs(float_distance(min, max)) < 2)
+               {
+                  result = guess = (min + max) / 2;
+                  break;
+               }
+               delta = bracket_root_towards_max(f, guess, f0, min, max, count);
+               result = guess - delta;
+               guess = min;
+               continue;
+            }
+         }
+         // update brackets:
+         if (delta > 0)
+         {
+            max = guess;
+            max_range_f = f0;
+         }
+         else
+         {
+            min = guess;
+            min_range_f = f0;
+         }
+         //
+         // Sanity check that we bracket the root:
+         //
+         if (max_range_f * min_range_f > 0)
+         {
+            return policies::raise_evaluation_error(function, "There appears to be no root to be found in boost::math::tools::newton_raphson_iterate, perhaps we have a local minima near current best guess of %1%", guess, boost::math::policies::policy<>());
+         }
+      } while(count && (fabs(result * factor) < fabs(delta)));
+
+      max_iter -= count;
+
+   #ifdef BOOST_MATH_INSTRUMENT
+      std::cout << "Second order root finder, final iteration count = " << max_iter << std::endl;
+   #endif
+
+      return result;
+   }
+} // T second_order_root_finder
+
+template <class F, class T>
+T halley_iterate(F f, T guess, T min, T max, int digits, boost::uintmax_t& max_iter) BOOST_NOEXCEPT_IF(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
+{
+   return detail::second_order_root_finder<detail::halley_step>(f, guess, min, max, digits, max_iter);
+}
+
+template <class F, class T>
+inline T halley_iterate(F f, T guess, T min, T max, int digits) BOOST_NOEXCEPT_IF(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
+{
+   boost::uintmax_t m = (std::numeric_limits<boost::uintmax_t>::max)();
+   return halley_iterate(f, guess, min, max, digits, m);
+}
+
+namespace detail {
+
+   struct schroder_stepper
+   {
+      template <class T>
+      static T step(const T& x, const T& f0, const T& f1, const T& f2) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(T))
+      {
+         using std::fabs;
+         T ratio = f0 / f1;
+         T delta;
+         if ((x != 0) && (fabs(ratio / x) < 0.1))
+         {
+            delta = ratio + (f2 / (2 * f1)) * ratio * ratio;
+            // check second derivative doesn't over compensate:
+            if (delta * ratio < 0)
+               delta = ratio;
+         }
+         else
+            delta = ratio;  // fall back to Newton iteration.
+         return delta;
+      }
+   };
+
+}
+
+template <class F, class T>
+T schroder_iterate(F f, T guess, T min, T max, int digits, boost::uintmax_t& max_iter) BOOST_NOEXCEPT_IF(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
+{
+   return detail::second_order_root_finder<detail::schroder_stepper>(f, guess, min, max, digits, max_iter);
+}
+
+template <class F, class T>
+inline T schroder_iterate(F f, T guess, T min, T max, int digits) BOOST_NOEXCEPT_IF(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
+{
+   boost::uintmax_t m = (std::numeric_limits<boost::uintmax_t>::max)();
+   return schroder_iterate(f, guess, min, max, digits, m);
+}
+//
+// These two are the old spelling of this function, retained for backwards compatibility just in case:
+//
+template <class F, class T>
+T schroeder_iterate(F f, T guess, T min, T max, int digits, boost::uintmax_t& max_iter) BOOST_NOEXCEPT_IF(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
+{
+   return detail::second_order_root_finder<detail::schroder_stepper>(f, guess, min, max, digits, max_iter);
+}
+
+template <class F, class T>
+inline T schroeder_iterate(F f, T guess, T min, T max, int digits) BOOST_NOEXCEPT_IF(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>())))
+{
+   boost::uintmax_t m = (std::numeric_limits<boost::uintmax_t>::max)();
+   return schroder_iterate(f, guess, min, max, digits, m);
+}
+
+#ifndef BOOST_NO_CXX11_AUTO_DECLARATIONS
+/*
+   * Why do we set the default maximum number of iterations to the number of digits in the type?
+   * Because for double roots, the number of digits increases linearly with the number of iterations,
+   * so this default should recover full precision even in this somewhat pathological case.
+   * For isolated roots, the problem is so rapidly convergent that this doesn't matter at all.
+   */
+template<class Complex, class F>
+Complex complex_newton(F g, Complex guess, int max_iterations = std::numeric_limits<typename Complex::value_type>::digits)
+{
+   typedef typename Complex::value_type Real;
+   using std::norm;
+   using std::abs;
+   using std::max;
+   // z0, z1, and z2 cannot be the same, in case we immediately need to resort to Muller's Method:
+   Complex z0 = guess + Complex(1, 0);
+   Complex z1 = guess + Complex(0, 1);
+   Complex z2 = guess;
+
+   do {
+      auto pair = g(z2);
+      if (norm(pair.second) == 0)
+      {
+         // Muller's method. Notation follows Numerical Recipes, 9.5.2:
+         Complex q = (z2 - z1) / (z1 - z0);
+         auto P0 = g(z0);
+         auto P1 = g(z1);
+         Complex qp1 = static_cast<Complex>(1) + q;
+         Complex A = q * (pair.first - qp1 * P1.first + q * P0.first);
+
+         Complex B = (static_cast<Complex>(2) * q + static_cast<Complex>(1)) * pair.first - qp1 * qp1 * P1.first + q * q * P0.first;
+         Complex C = qp1 * pair.first;
+         Complex rad = sqrt(B * B - static_cast<Complex>(4) * A * C);
+         Complex denom1 = B + rad;
+         Complex denom2 = B - rad;
+         Complex correction = (z1 - z2) * static_cast<Complex>(2) * C;
+         if (norm(denom1) > norm(denom2))
+         {
+            correction /= denom1;
+         }
+         else
+         {
+            correction /= denom2;
+         }
+
+         z0 = z1;
+         z1 = z2;
+         z2 = z2 + correction;
+      }
+      else
+      {
+         z0 = z1;
+         z1 = z2;
+         z2 = z2 - (pair.first / pair.second);
+      }
+
+      // See: https://math.stackexchange.com/questions/3017766/constructing-newton-iteration-converging-to-non-root
+      // If f' is continuous, then convergence of x_n -> x* implies f(x*) = 0.
+      // This condition approximates this convergence condition by requiring three consecutive iterates to be clustered.
+      Real tol = (max)(abs(z2) * std::numeric_limits<Real>::epsilon(), std::numeric_limits<Real>::epsilon());
+      bool real_close = abs(z0.real() - z1.real()) < tol && abs(z0.real() - z2.real()) < tol && abs(z1.real() - z2.real()) < tol;
+      bool imag_close = abs(z0.imag() - z1.imag()) < tol && abs(z0.imag() - z2.imag()) < tol && abs(z1.imag() - z2.imag()) < tol;
+      if (real_close && imag_close)
+      {
+         return z2;
+      }
+
+   } while (max_iterations--);
+
+   // The idea is that if we can get abs(f) < eps, we should, but if we go through all these iterations
+   // and abs(f) < sqrt(eps), then roundoff error simply does not allow that we can evaluate f to < eps
+   // This is somewhat awkward as it isn't scale invariant, but using the Daubechies coefficient example code,
+   // I found this condition generates correct roots, whereas the scale invariant condition discussed here:
+   // https://scicomp.stackexchange.com/questions/30597/defining-a-condition-number-and-termination-criteria-for-newtons-method
+   // allows nonroots to be passed off as roots.
+   auto pair = g(z2);
+   if (abs(pair.first) < sqrt(std::numeric_limits<Real>::epsilon()))
+   {
+      return z2;
+   }
+
+   return { std::numeric_limits<Real>::quiet_NaN(),
+            std::numeric_limits<Real>::quiet_NaN() };
+}
+#endif
+
+
+#if !defined(BOOST_NO_CXX17_IF_CONSTEXPR)
+// https://stackoverflow.com/questions/48979861/numerically-stable-method-for-solving-quadratic-equations/50065711
+namespace detail
+{
+#if defined(BOOST_GNU_STDLIB) && !defined(_GLIBCXX_USE_C99_MATH_TR1)
+inline float fma_workaround(float x, float y, float z) { return ::fmaf(x, y, z); }
+inline double fma_workaround(double x, double y, double z) { return ::fma(x, y, z); }
+#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+inline long double fma_workaround(long double x, long double y, long double z) { return ::fmal(x, y, z); }
+#endif
+#endif            
+template<class T>
+inline T discriminant(T const& a, T const& b, T const& c)
+{
+   T w = 4 * a * c;
+#if defined(BOOST_GNU_STDLIB) && !defined(_GLIBCXX_USE_C99_MATH_TR1)
+   T e = fma_workaround(-c, 4 * a, w);
+   T f = fma_workaround(b, b, -w);
+#else
+   T e = std::fma(-c, 4 * a, w);
+   T f = std::fma(b, b, -w);
+#endif
+   return f + e;
+}
+
+template<class T>
+std::pair<T, T> quadratic_roots_imp(T const& a, T const& b, T const& c)
+{
+#if defined(BOOST_GNU_STDLIB) && !defined(_GLIBCXX_USE_C99_MATH_TR1)
+   using boost::math::copysign;
+#else
+   using std::copysign;
+#endif
+   using std::sqrt;
+   if constexpr (std::is_floating_point<T>::value)
+   {
+      T nan = std::numeric_limits<T>::quiet_NaN();
+      if (a == 0)
+      {
+         if (b == 0 && c != 0)
+         {
+            return std::pair<T, T>(nan, nan);
+         }
+         else if (b == 0 && c == 0)
+         {
+            return std::pair<T, T>(0, 0);
+         }
+         return std::pair<T, T>(-c / b, -c / b);
+      }
+      if (b == 0)
+      {
+         T x0_sq = -c / a;
+         if (x0_sq < 0) {
+            return std::pair<T, T>(nan, nan);
+         }
+         T x0 = sqrt(x0_sq);
+         return std::pair<T, T>(-x0, x0);
+      }
+      T discriminant = detail::discriminant(a, b, c);
+      // Is there a sane way to flush very small negative values to zero?
+      // If there is I don't know of it.
+      if (discriminant < 0)
+      {
+         return std::pair<T, T>(nan, nan);
+      }
+      T q = -(b + copysign(sqrt(discriminant), b)) / T(2);
+      T x0 = q / a;
+      T x1 = c / q;
+      if (x0 < x1)
+      {
+         return std::pair<T, T>(x0, x1);
+      }
+      return std::pair<T, T>(x1, x0);
+   }
+   else if constexpr (boost::math::tools::is_complex_type<T>::value)
+   {
+      typename T::value_type nan = std::numeric_limits<typename T::value_type>::quiet_NaN();
+      if (a.real() == 0 && a.imag() == 0)
+      {
+         using std::norm;
+         if (b.real() == 0 && b.imag() && norm(c) != 0)
+         {
+            return std::pair<T, T>({ nan, nan }, { nan, nan });
+         }
+         else if (b.real() == 0 && b.imag() && c.real() == 0 && c.imag() == 0)
+         {
+            return std::pair<T, T>({ 0,0 }, { 0,0 });
+         }
+         return std::pair<T, T>(-c / b, -c / b);
+      }
+      if (b.real() == 0 && b.imag() == 0)
+      {
+         T x0_sq = -c / a;
+         T x0 = sqrt(x0_sq);
+         return std::pair<T, T>(-x0, x0);
+      }
+      // There's no fma for complex types:
+      T discriminant = b * b - T(4) * a * c;
+      T q = -(b + sqrt(discriminant)) / T(2);
+      return std::pair<T, T>(q / a, c / q);
+   }
+   else // Most likely the type is a boost.multiprecision.
+   {    //There is no fma for multiprecision, and in addition it doesn't seem to be useful, so revert to the naive computation.
+      T nan = std::numeric_limits<T>::quiet_NaN();
+      if (a == 0)
+      {
+         if (b == 0 && c != 0)
+         {
+            return std::pair<T, T>(nan, nan);
+         }
+         else if (b == 0 && c == 0)
+         {
+            return std::pair<T, T>(0, 0);
+         }
+         return std::pair<T, T>(-c / b, -c / b);
+      }
+      if (b == 0)
+      {
+         T x0_sq = -c / a;
+         if (x0_sq < 0) {
+            return std::pair<T, T>(nan, nan);
+         }
+         T x0 = sqrt(x0_sq);
+         return std::pair<T, T>(-x0, x0);
+      }
+      T discriminant = b * b - 4 * a * c;
+      if (discriminant < 0)
+      {
+         return std::pair<T, T>(nan, nan);
+      }
+      T q = -(b + copysign(sqrt(discriminant), b)) / T(2);
+      T x0 = q / a;
+      T x1 = c / q;
+      if (x0 < x1)
+      {
+         return std::pair<T, T>(x0, x1);
+      }
+      return std::pair<T, T>(x1, x0);
+   }
+}
+}  // namespace detail
+
+template<class T1, class T2 = T1, class T3 = T1>
+inline std::pair<typename tools::promote_args<T1, T2, T3>::type, typename tools::promote_args<T1, T2, T3>::type> quadratic_roots(T1 const& a, T2 const& b, T3 const& c)
+{
+   typedef typename tools::promote_args<T1, T2, T3>::type value_type;
+   return detail::quadratic_roots_imp(static_cast<value_type>(a), static_cast<value_type>(b), static_cast<value_type>(c));
+}
+
+#endif
+
+} // namespace tools
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_TOOLS_NEWTON_SOLVER_HPP
diff --git a/ThirdParty/boost/math/tools/series.hpp b/ThirdParty/boost/math/tools/series.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..8816f47a90bcf23fcbb807c36c4274ad15d8a5e0
--- /dev/null
+++ b/ThirdParty/boost/math/tools/series.hpp
@@ -0,0 +1,184 @@
+//  (C) Copyright John Maddock 2005-2006.
+//  Use, modification and distribution are subject to 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_TOOLS_SERIES_INCLUDED
+#define BOOST_MATH_TOOLS_SERIES_INCLUDED
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/limits.hpp>
+#include <boost/math/tools/config.hpp>
+
+namespace boost{ namespace math{ namespace tools{
+
+//
+// Simple series summation come first:
+//
+template <class Functor, class U, class V>
+inline typename Functor::result_type sum_series(Functor& func, const U& factor, boost::uintmax_t& max_terms, const V& init_value) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
+{
+   BOOST_MATH_STD_USING
+
+   typedef typename Functor::result_type result_type;
+
+   boost::uintmax_t counter = max_terms;
+
+   result_type result = init_value;
+   result_type next_term;
+   do{
+      next_term = func();
+      result += next_term;
+   }
+   while((abs(factor * result) < abs(next_term)) && --counter);
+
+   // set max_terms to the actual number of terms of the series evaluated:
+   max_terms = max_terms - counter;
+
+   return result;
+}
+
+template <class Functor, class U>
+inline typename Functor::result_type sum_series(Functor& func, const U& factor, boost::uintmax_t& max_terms) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
+{
+   typename Functor::result_type init_value = 0;
+   return sum_series(func, factor, max_terms, init_value);
+}
+
+template <class Functor, class U>
+inline typename Functor::result_type sum_series(Functor& func, int bits, boost::uintmax_t& max_terms, const U& init_value) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
+{
+   BOOST_MATH_STD_USING
+   typedef typename Functor::result_type result_type;
+   result_type factor = ldexp(result_type(1), 1 - bits);
+   return sum_series(func, factor, max_terms, init_value);
+}
+
+template <class Functor>
+inline typename Functor::result_type sum_series(Functor& func, int bits) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
+{
+   BOOST_MATH_STD_USING
+   typedef typename Functor::result_type result_type;
+   boost::uintmax_t iters = (std::numeric_limits<boost::uintmax_t>::max)();
+   result_type init_val = 0;
+   return sum_series(func, bits, iters, init_val);
+}
+
+template <class Functor>
+inline typename Functor::result_type sum_series(Functor& func, int bits, boost::uintmax_t& max_terms) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
+{
+   BOOST_MATH_STD_USING
+   typedef typename Functor::result_type result_type;
+   result_type init_val = 0;
+   return sum_series(func, bits, max_terms, init_val);
+}
+
+template <class Functor, class U>
+inline typename Functor::result_type sum_series(Functor& func, int bits, const U& init_value) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
+{
+   BOOST_MATH_STD_USING
+   boost::uintmax_t iters = (std::numeric_limits<boost::uintmax_t>::max)();
+   return sum_series(func, bits, iters, init_value);
+}
+//
+// Checked summation:
+//
+template <class Functor, class U, class V>
+inline typename Functor::result_type checked_sum_series(Functor& func, const U& factor, boost::uintmax_t& max_terms, const V& init_value, V& norm) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
+{
+   BOOST_MATH_STD_USING
+
+   typedef typename Functor::result_type result_type;
+
+   boost::uintmax_t counter = max_terms;
+
+   result_type result = init_value;
+   result_type next_term;
+   do {
+      next_term = func();
+      result += next_term;
+      norm += fabs(next_term);
+   } while ((abs(factor * result) < abs(next_term)) && --counter);
+
+   // set max_terms to the actual number of terms of the series evaluated:
+   max_terms = max_terms - counter;
+
+   return result;
+}
+
+
+//
+// Algorithm kahan_sum_series invokes Functor func until the N'th
+// term is too small to have any effect on the total, the terms
+// are added using the Kahan summation method.
+//
+// CAUTION: Optimizing compilers combined with extended-precision
+// machine registers conspire to render this algorithm partly broken:
+// double rounding of intermediate terms (first to a long double machine
+// register, and then to a double result) cause the rounding error computed
+// by the algorithm to be off by up to 1ulp.  However this occurs rarely, and
+// in any case the result is still much better than a naive summation.
+//
+template <class Functor>
+inline typename Functor::result_type kahan_sum_series(Functor& func, int bits) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
+{
+   BOOST_MATH_STD_USING
+
+   typedef typename Functor::result_type result_type;
+
+   result_type factor = pow(result_type(2), bits);
+   result_type result = func();
+   result_type next_term, y, t;
+   result_type carry = 0;
+   do{
+      next_term = func();
+      y = next_term - carry;
+      t = result + y;
+      carry = t - result;
+      carry -= y;
+      result = t;
+   }
+   while(fabs(result) < fabs(factor * next_term));
+   return result;
+}
+
+template <class Functor>
+inline typename Functor::result_type kahan_sum_series(Functor& func, int bits, boost::uintmax_t& max_terms) BOOST_NOEXCEPT_IF(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval<Functor>()()))
+{
+   BOOST_MATH_STD_USING
+
+   typedef typename Functor::result_type result_type;
+
+   boost::uintmax_t counter = max_terms;
+
+   result_type factor = ldexp(result_type(1), bits);
+   result_type result = func();
+   result_type next_term, y, t;
+   result_type carry = 0;
+   do{
+      next_term = func();
+      y = next_term - carry;
+      t = result + y;
+      carry = t - result;
+      carry -= y;
+      result = t;
+   }
+   while((fabs(result) < fabs(factor * next_term)) && --counter);
+
+   // set max_terms to the actual number of terms of the series evaluated:
+   max_terms = max_terms - counter;
+
+   return result;
+}
+
+} // namespace tools
+} // namespace math
+} // namespace boost
+
+#endif // BOOST_MATH_TOOLS_SERIES_INCLUDED
+
diff --git a/ThirdParty/boost/math/tools/toms748_solve.hpp b/ThirdParty/boost/math/tools/toms748_solve.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a044d112f872be480c920459738c8276fc7f16e1
--- /dev/null
+++ b/ThirdParty/boost/math/tools/toms748_solve.hpp
@@ -0,0 +1,621 @@
+//  (C) Copyright John Maddock 2006.
+//  Use, modification and distribution are subject to 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_TOOLS_SOLVE_ROOT_HPP
+#define BOOST_MATH_TOOLS_SOLVE_ROOT_HPP
+
+#ifdef _MSC_VER
+#pragma once
+#endif
+
+#include <boost/math/tools/precision.hpp>
+#include <boost/math/policies/error_handling.hpp>
+#include <boost/math/tools/config.hpp>
+#include <boost/math/special_functions/sign.hpp>
+#include <boost/cstdint.hpp>
+#include <limits>
+
+#ifdef BOOST_MATH_LOG_ROOT_ITERATIONS
+#  define BOOST_MATH_LOGGER_INCLUDE <boost/math/tools/iteration_logger.hpp>
+#  include BOOST_MATH_LOGGER_INCLUDE
+#  undef BOOST_MATH_LOGGER_INCLUDE
+#else
+#  define BOOST_MATH_LOG_COUNT(count)
+#endif
+
+namespace boost{ namespace math{ namespace tools{
+
+template <class T>
+class eps_tolerance
+{
+public:
+   eps_tolerance()
+   {
+      eps = 4 * tools::epsilon<T>();
+   }
+   eps_tolerance(unsigned bits)
+   {
+      BOOST_MATH_STD_USING
+      eps = (std::max)(T(ldexp(1.0F, 1-bits)), T(4 * tools::epsilon<T>()));
+   }
+   bool operator()(const T& a, const T& b)
+   {
+      BOOST_MATH_STD_USING
+      return fabs(a - b) <= (eps * (std::min)(fabs(a), fabs(b)));
+   }
+private:
+   T eps;
+};
+
+struct equal_floor
+{
+   equal_floor(){}
+   template <class T>
+   bool operator()(const T& a, const T& b)
+   {
+      BOOST_MATH_STD_USING
+      return floor(a) == floor(b);
+   }
+};
+
+struct equal_ceil
+{
+   equal_ceil(){}
+   template <class T>
+   bool operator()(const T& a, const T& b)
+   {
+      BOOST_MATH_STD_USING
+      return ceil(a) == ceil(b);
+   }
+};
+
+struct equal_nearest_integer
+{
+   equal_nearest_integer(){}
+   template <class T>
+   bool operator()(const T& a, const T& b)
+   {
+      BOOST_MATH_STD_USING
+      return floor(a + 0.5f) == floor(b + 0.5f);
+   }
+};
+
+namespace detail{
+
+template <class F, class T>
+void bracket(F f, T& a, T& b, T c, T& fa, T& fb, T& d, T& fd)
+{
+   //
+   // Given a point c inside the existing enclosing interval
+   // [a, b] sets a = c if f(c) == 0, otherwise finds the new 
+   // enclosing interval: either [a, c] or [c, b] and sets
+   // d and fd to the point that has just been removed from
+   // the interval.  In other words d is the third best guess
+   // to the root.
+   //
+   BOOST_MATH_STD_USING  // For ADL of std math functions
+   T tol = tools::epsilon<T>() * 2;
+   //
+   // If the interval [a,b] is very small, or if c is too close 
+   // to one end of the interval then we need to adjust the
+   // location of c accordingly:
+   //
+   if((b - a) < 2 * tol * a)
+   {
+      c = a + (b - a) / 2;
+   }
+   else if(c <= a + fabs(a) * tol)
+   {
+      c = a + fabs(a) * tol;
+   }
+   else if(c >= b - fabs(b) * tol)
+   {
+      c = b - fabs(b) * tol;
+   }
+   //
+   // OK, lets invoke f(c):
+   //
+   T fc = f(c);
+   //
+   // if we have a zero then we have an exact solution to the root:
+   //
+   if(fc == 0)
+   {
+      a = c;
+      fa = 0;
+      d = 0;
+      fd = 0;
+      return;
+   }
+   //
+   // Non-zero fc, update the interval:
+   //
+   if(boost::math::sign(fa) * boost::math::sign(fc) < 0)
+   {
+      d = b;
+      fd = fb;
+      b = c;
+      fb = fc;
+   }
+   else
+   {
+      d = a;
+      fd = fa;
+      a = c;
+      fa= fc;
+   }
+}
+
+template <class T>
+inline T safe_div(T num, T denom, T r)
+{
+   //
+   // return num / denom without overflow,
+   // return r if overflow would occur.
+   //
+   BOOST_MATH_STD_USING  // For ADL of std math functions
+
+   if(fabs(denom) < 1)
+   {
+      if(fabs(denom * tools::max_value<T>()) <= fabs(num))
+         return r;
+   }
+   return num / denom;
+}
+
+template <class T>
+inline T secant_interpolate(const T& a, const T& b, const T& fa, const T& fb)
+{
+   //
+   // Performs standard secant interpolation of [a,b] given
+   // function evaluations f(a) and f(b).  Performs a bisection
+   // if secant interpolation would leave us very close to either
+   // a or b.  Rationale: we only call this function when at least
+   // one other form of interpolation has already failed, so we know
+   // that the function is unlikely to be smooth with a root very
+   // close to a or b.
+   //
+   BOOST_MATH_STD_USING  // For ADL of std math functions
+
+   T tol = tools::epsilon<T>() * 5;
+   T c = a - (fa / (fb - fa)) * (b - a);
+   if((c <= a + fabs(a) * tol) || (c >= b - fabs(b) * tol))
+      return (a + b) / 2;
+   return c;
+}
+
+template <class T>
+T quadratic_interpolate(const T& a, const T& b, T const& d,
+                           const T& fa, const T& fb, T const& fd, 
+                           unsigned count)
+{
+   //
+   // Performs quadratic interpolation to determine the next point,
+   // takes count Newton steps to find the location of the
+   // quadratic polynomial.
+   //
+   // Point d must lie outside of the interval [a,b], it is the third
+   // best approximation to the root, after a and b.
+   //
+   // Note: this does not guarantee to find a root
+   // inside [a, b], so we fall back to a secant step should
+   // the result be out of range.
+   //
+   // Start by obtaining the coefficients of the quadratic polynomial:
+   //
+   T B = safe_div(T(fb - fa), T(b - a), tools::max_value<T>());
+   T A = safe_div(T(fd - fb), T(d - b), tools::max_value<T>());
+   A = safe_div(T(A - B), T(d - a), T(0));
+
+   if(A == 0)
+   {
+      // failure to determine coefficients, try a secant step:
+      return secant_interpolate(a, b, fa, fb);
+   }
+   //
+   // Determine the starting point of the Newton steps:
+   //
+   T c;
+   if(boost::math::sign(A) * boost::math::sign(fa) > 0)
+   {
+      c = a;
+   }
+   else
+   {
+      c = b;
+   }
+   //
+   // Take the Newton steps:
+   //
+   for(unsigned i = 1; i <= count; ++i)
+   {
+      //c -= safe_div(B * c, (B + A * (2 * c - a - b)), 1 + c - a);
+      c -= safe_div(T(fa+(B+A*(c-b))*(c-a)), T(B + A * (2 * c - a - b)), T(1 + c - a));
+   }
+   if((c <= a) || (c >= b))
+   {
+      // Oops, failure, try a secant step:
+      c = secant_interpolate(a, b, fa, fb);
+   }
+   return c;
+}
+
+template <class T>
+T cubic_interpolate(const T& a, const T& b, const T& d, 
+                    const T& e, const T& fa, const T& fb, 
+                    const T& fd, const T& fe)
+{
+   //
+   // Uses inverse cubic interpolation of f(x) at points 
+   // [a,b,d,e] to obtain an approximate root of f(x).
+   // Points d and e lie outside the interval [a,b]
+   // and are the third and forth best approximations
+   // to the root that we have found so far.
+   //
+   // Note: this does not guarantee to find a root
+   // inside [a, b], so we fall back to quadratic
+   // interpolation in case of an erroneous result.
+   //
+   BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b
+      << " d = " << d << " e = " << e << " fa = " << fa << " fb = " << fb 
+      << " fd = " << fd << " fe = " << fe);
+   T q11 = (d - e) * fd / (fe - fd);
+   T q21 = (b - d) * fb / (fd - fb);
+   T q31 = (a - b) * fa / (fb - fa);
+   T d21 = (b - d) * fd / (fd - fb);
+   T d31 = (a - b) * fb / (fb - fa);
+   BOOST_MATH_INSTRUMENT_CODE(
+      "q11 = " << q11 << " q21 = " << q21 << " q31 = " << q31
+      << " d21 = " << d21 << " d31 = " << d31);
+   T q22 = (d21 - q11) * fb / (fe - fb);
+   T q32 = (d31 - q21) * fa / (fd - fa);
+   T d32 = (d31 - q21) * fd / (fd - fa);
+   T q33 = (d32 - q22) * fa / (fe - fa);
+   T c = q31 + q32 + q33 + a;
+   BOOST_MATH_INSTRUMENT_CODE(
+      "q22 = " << q22 << " q32 = " << q32 << " d32 = " << d32
+      << " q33 = " << q33 << " c = " << c);
+
+   if((c <= a) || (c >= b))
+   {
+      // Out of bounds step, fall back to quadratic interpolation:
+      c = quadratic_interpolate(a, b, d, fa, fb, fd, 3);
+   BOOST_MATH_INSTRUMENT_CODE(
+      "Out of bounds interpolation, falling back to quadratic interpolation. c = " << c);
+   }
+
+   return c;
+}
+
+} // namespace detail
+
+template <class F, class T, class Tol, class Policy>
+std::pair<T, T> toms748_solve(F f, const T& ax, const T& bx, const T& fax, const T& fbx, Tol tol, boost::uintmax_t& max_iter, const Policy& pol)
+{
+   //
+   // Main entry point and logic for Toms Algorithm 748
+   // root finder.
+   //
+   BOOST_MATH_STD_USING  // For ADL of std math functions
+
+   static const char* function = "boost::math::tools::toms748_solve<%1%>";
+
+   //
+   // Sanity check - are we allowed to iterate at all?
+   //
+   if (max_iter == 0)
+      return std::make_pair(ax, bx);
+
+   boost::uintmax_t count = max_iter;
+   T a, b, fa, fb, c, u, fu, a0, b0, d, fd, e, fe;
+   static const T mu = 0.5f;
+
+   // initialise a, b and fa, fb:
+   a = ax;
+   b = bx;
+   if(a >= b)
+      return boost::math::detail::pair_from_single(policies::raise_domain_error(
+         function, 
+         "Parameters a and b out of order: a=%1%", a, pol));
+   fa = fax;
+   fb = fbx;
+
+   if(tol(a, b) || (fa == 0) || (fb == 0))
+   {
+      max_iter = 0;
+      if(fa == 0)
+         b = a;
+      else if(fb == 0)
+         a = b;
+      return std::make_pair(a, b);
+   }
+
+   if(boost::math::sign(fa) * boost::math::sign(fb) > 0)
+      return boost::math::detail::pair_from_single(policies::raise_domain_error(
+         function, 
+         "Parameters a and b do not bracket the root: a=%1%", a, pol));
+   // dummy value for fd, e and fe:
+   fe = e = fd = 1e5F;
+
+   if(fa != 0)
+   {
+      //
+      // On the first step we take a secant step:
+      //
+      c = detail::secant_interpolate(a, b, fa, fb);
+      detail::bracket(f, a, b, c, fa, fb, d, fd);
+      --count;
+      BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b);
+
+      if(count && (fa != 0) && !tol(a, b))
+      {
+         //
+         // On the second step we take a quadratic interpolation:
+         //
+         c = detail::quadratic_interpolate(a, b, d, fa, fb, fd, 2);
+         e = d;
+         fe = fd;
+         detail::bracket(f, a, b, c, fa, fb, d, fd);
+         --count;
+         BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b);
+      }
+   }
+
+   while(count && (fa != 0) && !tol(a, b))
+   {
+      // save our brackets:
+      a0 = a;
+      b0 = b;
+      //
+      // Starting with the third step taken
+      // we can use either quadratic or cubic interpolation.
+      // Cubic interpolation requires that all four function values
+      // fa, fb, fd, and fe are distinct, should that not be the case
+      // then variable prof will get set to true, and we'll end up
+      // taking a quadratic step instead.
+      //
+      T min_diff = tools::min_value<T>() * 32;
+      bool prof = (fabs(fa - fb) < min_diff) || (fabs(fa - fd) < min_diff) || (fabs(fa - fe) < min_diff) || (fabs(fb - fd) < min_diff) || (fabs(fb - fe) < min_diff) || (fabs(fd - fe) < min_diff);
+      if(prof)
+      {
+         c = detail::quadratic_interpolate(a, b, d, fa, fb, fd, 2);
+         BOOST_MATH_INSTRUMENT_CODE("Can't take cubic step!!!!");
+      }
+      else
+      {
+         c = detail::cubic_interpolate(a, b, d, e, fa, fb, fd, fe);
+      }
+      //
+      // re-bracket, and check for termination:
+      //
+      e = d;
+      fe = fd;
+      detail::bracket(f, a, b, c, fa, fb, d, fd);
+      if((0 == --count) || (fa == 0) || tol(a, b))
+         break;
+      BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b);
+      //
+      // Now another interpolated step:
+      //
+      prof = (fabs(fa - fb) < min_diff) || (fabs(fa - fd) < min_diff) || (fabs(fa - fe) < min_diff) || (fabs(fb - fd) < min_diff) || (fabs(fb - fe) < min_diff) || (fabs(fd - fe) < min_diff);
+      if(prof)
+      {
+         c = detail::quadratic_interpolate(a, b, d, fa, fb, fd, 3);
+         BOOST_MATH_INSTRUMENT_CODE("Can't take cubic step!!!!");
+      }
+      else
+      {
+         c = detail::cubic_interpolate(a, b, d, e, fa, fb, fd, fe);
+      }
+      //
+      // Bracket again, and check termination condition, update e:
+      //
+      detail::bracket(f, a, b, c, fa, fb, d, fd);
+      if((0 == --count) || (fa == 0) || tol(a, b))
+         break;
+      BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b);
+      //
+      // Now we take a double-length secant step:
+      //
+      if(fabs(fa) < fabs(fb))
+      {
+         u = a;
+         fu = fa;
+      }
+      else
+      {
+         u = b;
+         fu = fb;
+      }
+      c = u - 2 * (fu / (fb - fa)) * (b - a);
+      if(fabs(c - u) > (b - a) / 2)
+      {
+         c = a + (b - a) / 2;
+      }
+      //
+      // Bracket again, and check termination condition:
+      //
+      e = d;
+      fe = fd;
+      detail::bracket(f, a, b, c, fa, fb, d, fd);
+      BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b);
+      BOOST_MATH_INSTRUMENT_CODE(" tol = " << T((fabs(a) - fabs(b)) / fabs(a)));
+      if((0 == --count) || (fa == 0) || tol(a, b))
+         break;
+      //
+      // And finally... check to see if an additional bisection step is 
+      // to be taken, we do this if we're not converging fast enough:
+      //
+      if((b - a) < mu * (b0 - a0))
+         continue;
+      //
+      // bracket again on a bisection:
+      //
+      e = d;
+      fe = fd;
+      detail::bracket(f, a, b, T(a + (b - a) / 2), fa, fb, d, fd);
+      --count;
+      BOOST_MATH_INSTRUMENT_CODE("Not converging: Taking a bisection!!!!");
+      BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b);
+   } // while loop
+
+   max_iter -= count;
+   if(fa == 0)
+   {
+      b = a;
+   }
+   else if(fb == 0)
+   {
+      a = b;
+   }
+   BOOST_MATH_LOG_COUNT(max_iter)
+   return std::make_pair(a, b);
+}
+
+template <class F, class T, class Tol>
+inline std::pair<T, T> toms748_solve(F f, const T& ax, const T& bx, const T& fax, const T& fbx, Tol tol, boost::uintmax_t& max_iter)
+{
+   return toms748_solve(f, ax, bx, fax, fbx, tol, max_iter, policies::policy<>());
+}
+
+template <class F, class T, class Tol, class Policy>
+inline std::pair<T, T> toms748_solve(F f, const T& ax, const T& bx, Tol tol, boost::uintmax_t& max_iter, const Policy& pol)
+{
+   if (max_iter <= 2)
+      return std::make_pair(ax, bx);
+   max_iter -= 2;
+   std::pair<T, T> r = toms748_solve(f, ax, bx, f(ax), f(bx), tol, max_iter, pol);
+   max_iter += 2;
+   return r;
+}
+
+template <class F, class T, class Tol>
+inline std::pair<T, T> toms748_solve(F f, const T& ax, const T& bx, Tol tol, boost::uintmax_t& max_iter)
+{
+   return toms748_solve(f, ax, bx, tol, max_iter, policies::policy<>());
+}
+
+template <class F, class T, class Tol, class Policy>
+std::pair<T, T> bracket_and_solve_root(F f, const T& guess, T factor, bool rising, Tol tol, boost::uintmax_t& max_iter, const Policy& pol)
+{
+   BOOST_MATH_STD_USING
+   static const char* function = "boost::math::tools::bracket_and_solve_root<%1%>";
+   //
+   // Set up initial brackets:
+   //
+   T a = guess;
+   T b = a;
+   T fa = f(a);
+   T fb = fa;
+   //
+   // Set up invocation count:
+   //
+   boost::uintmax_t count = max_iter - 1;
+
+   int step = 32;
+
+   if((fa < 0) == (guess < 0 ? !rising : rising))
+   {
+      //
+      // Zero is to the right of b, so walk upwards
+      // until we find it:
+      //
+      while((boost::math::sign)(fb) == (boost::math::sign)(fa))
+      {
+         if(count == 0)
+            return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", b, pol));
+         //
+         // Heuristic: normally it's best not to increase the step sizes as we'll just end up
+         // with a really wide range to search for the root.  However, if the initial guess was *really*
+         // bad then we need to speed up the search otherwise we'll take forever if we're orders of
+         // magnitude out.  This happens most often if the guess is a small value (say 1) and the result
+         // we're looking for is close to std::numeric_limits<T>::min().
+         //
+         if((max_iter - count) % step == 0)
+         {
+            factor *= 2;
+            if(step > 1) step /= 2;
+         }
+         //
+         // Now go ahead and move our guess by "factor":
+         //
+         a = b;
+         fa = fb;
+         b *= factor;
+         fb = f(b);
+         --count;
+         BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count);
+      }
+   }
+   else
+   {
+      //
+      // Zero is to the left of a, so walk downwards
+      // until we find it:
+      //
+      while((boost::math::sign)(fb) == (boost::math::sign)(fa))
+      {
+         if(fabs(a) < tools::min_value<T>())
+         {
+            // Escape route just in case the answer is zero!
+            max_iter -= count;
+            max_iter += 1;
+            return a > 0 ? std::make_pair(T(0), T(a)) : std::make_pair(T(a), T(0)); 
+         }
+         if(count == 0)
+            return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", a, pol));
+         //
+         // Heuristic: normally it's best not to increase the step sizes as we'll just end up
+         // with a really wide range to search for the root.  However, if the initial guess was *really*
+         // bad then we need to speed up the search otherwise we'll take forever if we're orders of
+         // magnitude out.  This happens most often if the guess is a small value (say 1) and the result
+         // we're looking for is close to std::numeric_limits<T>::min().
+         //
+         if((max_iter - count) % step == 0)
+         {
+            factor *= 2;
+            if(step > 1) step /= 2;
+         }
+         //
+         // Now go ahead and move are guess by "factor":
+         //
+         b = a;
+         fb = fa;
+         a /= factor;
+         fa = f(a);
+         --count;
+         BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count);
+      }
+   }
+   max_iter -= count;
+   max_iter += 1;
+   std::pair<T, T> r = toms748_solve(
+      f, 
+      (a < 0 ? b : a), 
+      (a < 0 ? a : b), 
+      (a < 0 ? fb : fa), 
+      (a < 0 ? fa : fb), 
+      tol, 
+      count, 
+      pol);
+   max_iter += count;
+   BOOST_MATH_INSTRUMENT_CODE("max_iter = " << max_iter << " count = " << count);
+   BOOST_MATH_LOG_COUNT(max_iter)
+   return r;
+}
+
+template <class F, class T, class Tol>
+inline std::pair<T, T> bracket_and_solve_root(F f, const T& guess, const T& factor, bool rising, Tol tol, boost::uintmax_t& max_iter)
+{
+   return bracket_and_solve_root(f, guess, factor, rising, tol, max_iter, policies::policy<>());
+}
+
+} // namespace tools
+} // namespace math
+} // namespace boost
+
+
+#endif // BOOST_MATH_TOOLS_SOLVE_ROOT_HPP
+
diff --git a/ThirdParty/boost/math/tools/tuple.hpp b/ThirdParty/boost/math/tools/tuple.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7ca57a1b648b5d9ff152a1bb70ce28c53062c88f
--- /dev/null
+++ b/ThirdParty/boost/math/tools/tuple.hpp
@@ -0,0 +1,92 @@
+//  (C) Copyright John Maddock 2010.
+//  Use, modification and distribution are subject to 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_TUPLE_HPP_INCLUDED
+#  define BOOST_MATH_TUPLE_HPP_INCLUDED
+#  include <boost/config.hpp>
+#  include <boost/detail/workaround.hpp>
+#  include <boost/math/tools/cxx03_warn.hpp>
+
+#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40500)
+
+#include <tuple>
+
+namespace boost{ namespace math{
+
+using ::std::tuple;
+
+// [6.1.3.2] Tuple creation functions
+using ::std::ignore;
+using ::std::make_tuple;
+using ::std::tie;
+using ::std::get;
+
+// [6.1.3.3] Tuple helper classes
+using ::std::tuple_size;
+using ::std::tuple_element;
+
+}}
+
+#elif (defined(__BORLANDC__) && (__BORLANDC__ <= 0x600)) || defined(__IBMCPP__)
+
+#include <boost/tuple/tuple.hpp>
+#include <boost/tuple/tuple_comparison.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+
+namespace boost{ namespace math{
+
+using ::boost::tuple;
+
+// [6.1.3.2] Tuple creation functions
+using ::boost::tuples::ignore;
+using ::boost::make_tuple;
+using ::boost::tie;
+
+// [6.1.3.3] Tuple helper classes
+template <class T> 
+struct tuple_size 
+   : public ::boost::integral_constant
+   < ::std::size_t, ::boost::tuples::length<T>::value>
+{};
+
+template < int I, class T>
+struct tuple_element
+{
+   typedef typename boost::tuples::element<I,T>::type type;
+};
+
+#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
+// [6.1.3.4] Element access
+using ::boost::get;
+#endif
+
+} } // namespaces
+
+#else
+
+#include <boost/fusion/include/tuple.hpp>
+#include <boost/fusion/include/std_pair.hpp>
+
+namespace boost{ namespace math{
+
+using ::boost::fusion::tuple;
+
+// [6.1.3.2] Tuple creation functions
+using ::boost::fusion::ignore;
+using ::boost::fusion::make_tuple;
+using ::boost::fusion::tie;
+using ::boost::fusion::get;
+
+// [6.1.3.3] Tuple helper classes
+using ::boost::fusion::tuple_size;
+using ::boost::fusion::tuple_element;
+
+}}
+
+#endif
+
+#endif
+
+
diff --git a/ThirdParty/boost/memory_order.hpp b/ThirdParty/boost/memory_order.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ba7d1cdd982619967865b6e87402ae7a0bdae8d6
--- /dev/null
+++ b/ThirdParty/boost/memory_order.hpp
@@ -0,0 +1,82 @@
+//  boost/memory_order.hpp
+//
+//  Defines enum boost::memory_order per the C++0x working draft
+//
+//  Copyright (c) 2008, 2009 Peter Dimov
+//  Copyright (c) 2018 Andrey Semashev
+//
+//  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_MEMORY_ORDER_HPP_INCLUDED
+#define BOOST_MEMORY_ORDER_HPP_INCLUDED
+
+#include <boost/config.hpp>
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+namespace boost
+{
+
+//
+// Enum values are chosen so that code that needs to insert
+// a trailing fence for acquire semantics can use a single
+// test such as:
+//
+// if( mo & memory_order_acquire ) { ...fence... }
+//
+// For leading fences one can use:
+//
+// if( mo & memory_order_release ) { ...fence... }
+//
+// Architectures such as Alpha that need a fence on consume
+// can use:
+//
+// if( mo & ( memory_order_acquire | memory_order_consume ) ) { ...fence... }
+//
+// The values are also in the order of increasing "strength"
+// of the fences so that success/failure orders can be checked
+// efficiently in compare_exchange methods.
+//
+
+#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
+
+enum class memory_order : unsigned int
+{
+    relaxed = 0,
+    consume = 1,
+    acquire = 2,
+    release = 4,
+    acq_rel = 6, // acquire | release
+    seq_cst = 14 // acq_rel | 8
+};
+
+BOOST_INLINE_VARIABLE BOOST_CONSTEXPR_OR_CONST memory_order memory_order_relaxed = memory_order::relaxed;
+BOOST_INLINE_VARIABLE BOOST_CONSTEXPR_OR_CONST memory_order memory_order_consume = memory_order::consume;
+BOOST_INLINE_VARIABLE BOOST_CONSTEXPR_OR_CONST memory_order memory_order_acquire = memory_order::acquire;
+BOOST_INLINE_VARIABLE BOOST_CONSTEXPR_OR_CONST memory_order memory_order_release = memory_order::release;
+BOOST_INLINE_VARIABLE BOOST_CONSTEXPR_OR_CONST memory_order memory_order_acq_rel = memory_order::acq_rel;
+BOOST_INLINE_VARIABLE BOOST_CONSTEXPR_OR_CONST memory_order memory_order_seq_cst = memory_order::seq_cst;
+
+#undef BOOST_MEMORY_ORDER_INLINE_VARIABLE
+
+#else // !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
+
+enum memory_order
+{
+    memory_order_relaxed = 0,
+    memory_order_consume = 1,
+    memory_order_acquire = 2,
+    memory_order_release = 4,
+    memory_order_acq_rel = 6, // acquire | release
+    memory_order_seq_cst = 14 // acq_rel | 8
+};
+
+#endif // !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
+
+} // namespace boost
+
+#endif // #ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED
diff --git a/ThirdParty/boost/tuple/tuple_comparison.hpp b/ThirdParty/boost/tuple/tuple_comparison.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..0a61952a78916cf741a77bd7d2bcba4e6bac9d2e
--- /dev/null
+++ b/ThirdParty/boost/tuple/tuple_comparison.hpp
@@ -0,0 +1,175 @@
+// tuple_comparison.hpp -----------------------------------------------------
+//
+// Copyright (C) 2001 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
+// Copyright (C) 2001 Gary Powell (gary.powell@sierra.com)
+//
+// 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)
+//
+// For more information, see http://www.boost.org
+//
+// (The idea and first impl. of comparison operators was from Doug Gregor)
+
+// -----------------------------------------------------------------
+
+#ifndef BOOST_TUPLE_COMPARISON_HPP
+#define BOOST_TUPLE_COMPARISON_HPP
+
+#include <boost/tuple/tuple.hpp>
+
+// -------------------------------------------------------------
+// equality and comparison operators
+//
+// == and != compare tuples elementwise
+// <, >, <= and >= use lexicographical ordering
+//
+// Any operator between tuples of different length fails at compile time
+// No dependencies between operators are assumed
+// (i.e. !(a<b)  does not imply a>=b, a!=b does not imply a==b etc.
+// so any weirdnesses of elementary operators are respected).
+//
+// -------------------------------------------------------------
+
+
+namespace boost {
+namespace tuples {
+
+inline bool operator==(const null_type&, const null_type&) { return true; }
+inline bool operator>=(const null_type&, const null_type&) { return true; }
+inline bool operator<=(const null_type&, const null_type&) { return true; }
+inline bool operator!=(const null_type&, const null_type&) { return false; }
+inline bool operator<(const null_type&, const null_type&) { return false; }
+inline bool operator>(const null_type&, const null_type&) { return false; }
+
+
+namespace detail {
+  // comparison operators check statically the length of its operands and
+  // delegate the comparing task to the following functions. Hence
+  // the static check is only made once (should help the compiler).
+  // These functions assume tuples to be of the same length.
+
+
+template<class T1, class T2>
+inline bool eq(const T1& lhs, const T2& rhs) {
+  return lhs.get_head() == rhs.get_head() &&
+         eq(lhs.get_tail(), rhs.get_tail());
+}
+template<>
+inline bool eq<null_type,null_type>(const null_type&, const null_type&) { return true; }
+
+template<class T1, class T2>
+inline bool neq(const T1& lhs, const T2& rhs) {
+  return lhs.get_head() != rhs.get_head()  ||
+         neq(lhs.get_tail(), rhs.get_tail());
+}
+template<>
+inline bool neq<null_type,null_type>(const null_type&, const null_type&) { return false; }
+
+template<class T1, class T2>
+inline bool lt(const T1& lhs, const T2& rhs) {
+  return lhs.get_head() < rhs.get_head()  ||
+          ( !(rhs.get_head() < lhs.get_head()) &&
+            lt(lhs.get_tail(), rhs.get_tail()));
+}
+template<>
+inline bool lt<null_type,null_type>(const null_type&, const null_type&) { return false; }
+
+template<class T1, class T2>
+inline bool gt(const T1& lhs, const T2& rhs) {
+  return lhs.get_head() > rhs.get_head()  ||
+          ( !(rhs.get_head() > lhs.get_head()) &&
+            gt(lhs.get_tail(), rhs.get_tail()));
+}
+template<>
+inline bool gt<null_type,null_type>(const null_type&, const null_type&) { return false; }
+
+template<class T1, class T2>
+inline bool lte(const T1& lhs, const T2& rhs) {
+  return lhs.get_head() <= rhs.get_head()  &&
+          ( !(rhs.get_head() <= lhs.get_head()) ||
+            lte(lhs.get_tail(), rhs.get_tail()));
+}
+template<>
+inline bool lte<null_type,null_type>(const null_type&, const null_type&) { return true; }
+
+template<class T1, class T2>
+inline bool gte(const T1& lhs, const T2& rhs) {
+  return lhs.get_head() >= rhs.get_head()  &&
+          ( !(rhs.get_head() >= lhs.get_head()) ||
+            gte(lhs.get_tail(), rhs.get_tail()));
+}
+template<>
+inline bool gte<null_type,null_type>(const null_type&, const null_type&) { return true; }
+
+} // end of namespace detail
+
+
+// equal ----
+
+template<class T1, class T2, class S1, class S2>
+inline bool operator==(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
+{
+  // check that tuple lengths are equal
+  BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
+
+  return  detail::eq(lhs, rhs);
+}
+
+// not equal -----
+
+template<class T1, class T2, class S1, class S2>
+inline bool operator!=(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
+{
+
+  // check that tuple lengths are equal
+  BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
+
+  return detail::neq(lhs, rhs);
+}
+
+// <
+template<class T1, class T2, class S1, class S2>
+inline bool operator<(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
+{
+  // check that tuple lengths are equal
+  BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
+
+  return detail::lt(lhs, rhs);
+}
+
+// >
+template<class T1, class T2, class S1, class S2>
+inline bool operator>(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
+{
+  // check that tuple lengths are equal
+  BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
+
+  return detail::gt(lhs, rhs);
+}
+
+// <=
+template<class T1, class T2, class S1, class S2>
+inline bool operator<=(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
+{
+  // check that tuple lengths are equal
+  BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
+
+  return detail::lte(lhs, rhs);
+}
+
+// >=
+template<class T1, class T2, class S1, class S2>
+inline bool operator>=(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
+{
+  // check that tuple lengths are equal
+  BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
+
+  return detail::gte(lhs, rhs);
+}
+
+} // end of namespace tuples
+} // end of namespace boost
+
+
+#endif // BOOST_TUPLE_COMPARISON_HPP
diff --git a/ThirdParty/boost/type_traits/detail/detector.hpp b/ThirdParty/boost/type_traits/detail/detector.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f13a1f94270f6f8d564cf975729a6af93710f9e1
--- /dev/null
+++ b/ThirdParty/boost/type_traits/detail/detector.hpp
@@ -0,0 +1,37 @@
+/*
+Copyright 2017-2018 Glen Joseph Fernandes
+(glenjofe@gmail.com)
+
+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_TT_DETAIL_DETECTOR_HPP_INCLUDED
+#define BOOST_TT_DETAIL_DETECTOR_HPP_INCLUDED
+
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/type_traits/make_void.hpp>
+
+namespace boost {
+namespace detail {
+
+template<class T>
+using detector_t = typename boost::make_void<T>::type;
+
+template<class Default, class, template<class...> class, class...>
+struct detector {
+    using value_t = boost::false_type;
+    using type = Default;
+};
+
+template<class Default, template<class...> class Op, class... Args>
+struct detector<Default, detector_t<Op<Args...> >, Op, Args...> {
+    using value_t = boost::true_type;
+    using type = Op<Args...>;
+};
+
+} /* detail */
+} /* boost */
+
+#endif
diff --git a/ThirdParty/boost/type_traits/is_detected.hpp b/ThirdParty/boost/type_traits/is_detected.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..25dfa848905eb712c4eaa1125b0befc3f28cd9e0
--- /dev/null
+++ b/ThirdParty/boost/type_traits/is_detected.hpp
@@ -0,0 +1,29 @@
+/*
+Copyright 2017-2018 Glen Joseph Fernandes
+(glenjofe@gmail.com)
+
+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_TT_IS_DETECTED_HPP_INCLUDED
+#define BOOST_TT_IS_DETECTED_HPP_INCLUDED
+
+#include <boost/type_traits/detail/detector.hpp>
+#include <boost/type_traits/nonesuch.hpp>
+
+namespace boost {
+
+template<template<class...> class Op, class... Args>
+using is_detected = typename
+    detail::detector<nonesuch, void, Op, Args...>::value_t;
+
+#if !defined(BOOST_NO_CXX14_VARIABLE_TEMPLATES)
+template<template<class...> class Op, class... Args>
+constexpr bool is_detected_v = is_detected<Op, Args...>::value;
+#endif
+
+} /* boost */
+
+#endif
diff --git a/ThirdParty/boost/type_traits/nonesuch.hpp b/ThirdParty/boost/type_traits/nonesuch.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7ba98c4bce8674883b75c86fbc55ee7e97cd61d7
--- /dev/null
+++ b/ThirdParty/boost/type_traits/nonesuch.hpp
@@ -0,0 +1,35 @@
+/*
+Copyright 2017 Glen Joseph Fernandes
+(glenjofe@gmail.com)
+
+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_TT_NONESUCH_HPP_INCLUDED
+#define BOOST_TT_NONESUCH_HPP_INCLUDED
+
+#include <boost/config.hpp>
+
+namespace boost {
+
+#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
+struct nonesuch {
+    nonesuch() = delete;
+    ~nonesuch() = delete;
+    nonesuch(const nonesuch&) = delete;
+    void operator=(const nonesuch&) = delete;
+};
+#else
+class nonesuch {
+    nonesuch();
+    ~nonesuch();
+    nonesuch(const nonesuch&);
+    void operator=(const nonesuch&);
+};
+#endif
+
+} /* boost */
+
+#endif