diff --git a/base/not_null.hpp b/base/not_null.hpp index d424da4b8d..1fd75b7188 100644 --- a/base/not_null.hpp +++ b/base/not_null.hpp @@ -138,13 +138,13 @@ struct NotNullStorage< // reference to its template argument. template using _checked_not_null = typename std::enable_if< - !is_instance_of_v::type>, + !instance_of::type, not_null>, not_null::type>>::type; // We cannot refer to the template |not_null| inside of |not_null|. template inline constexpr bool is_instance_of_not_null_v = - is_instance_of_v; + instance_of; // |not_null| is a wrapper for a non-null object of type |Pointer|. // |Pointer| should be a C-style pointer or a smart pointer. |Pointer| must not diff --git a/base/traits.hpp b/base/traits.hpp index d62399bdc5..70301a0d64 100644 --- a/base/traits.hpp +++ b/base/traits.hpp @@ -17,12 +17,13 @@ template constexpr bool all_different_v = (!std::is_same_v && ...) && all_different_v; - -template typename T, typename U> +// The order of template parameters matches std::is_base_of; the type name +// should be read as an infix, U is [an] instance of T. +template typename T> struct is_instance_of : std::false_type {}; template typename T, typename... Args> -struct is_instance_of> : std::true_type {}; +struct is_instance_of, T> : std::true_type {}; template typename T, @@ -56,13 +57,17 @@ struct other_type { using internal::all_different_v; // True if and only if U is an instance of T. -template typename T, typename U> -inline constexpr bool is_instance_of_v = internal::is_instance_of::value; +// The order of template parameters matches std::is_base_of; the type name +// should be read as an infix, U is [an] instance of T. +template typename T> +inline constexpr bool is_instance_of_v = internal::is_instance_of::value; -// Note the argument inversion so that we can use instance_of in a requires -// clause. +// The order of template parameters allows for +// requires { { expression } -> instance_of; } +// or +// template U> template typename T> -concept instance_of = is_instance_of_v; +concept instance_of = is_instance_of_v; // True if and only if T and U are the same template. template typename T, template typename U> diff --git "a/integrators/embedded_explicit_generalized_runge_kutta_nystr\303\266m_integrator.hpp" "b/integrators/embedded_explicit_generalized_runge_kutta_nystr\303\266m_integrator.hpp" index fabb96ee71..b647cc58ce 100644 --- "a/integrators/embedded_explicit_generalized_runge_kutta_nystr\303\266m_integrator.hpp" +++ "b/integrators/embedded_explicit_generalized_runge_kutta_nystr\303\266m_integrator.hpp" @@ -75,7 +75,7 @@ class EmbeddedExplicitGeneralizedRungeKuttaNyströmIntegrator public: using ODE = ODE_; static_assert( - is_instance_of_v); + instance_of); using typename Integrator::AppendState; using typename AdaptiveStepSizeIntegrator::Parameters; using typename AdaptiveStepSizeIntegrator::ToleranceToErrorRatio; diff --git a/integrators/embedded_explicit_runge_kutta_integrator.hpp b/integrators/embedded_explicit_runge_kutta_integrator.hpp index 8139c82d19..f5b359401e 100644 --- a/integrators/embedded_explicit_runge_kutta_integrator.hpp +++ b/integrators/embedded_explicit_runge_kutta_integrator.hpp @@ -54,7 +54,7 @@ class EmbeddedExplicitRungeKuttaIntegrator public: using ODE = ODE_; static_assert( - is_instance_of_v); + instance_of); using typename Integrator::AppendState; using typename AdaptiveStepSizeIntegrator::Parameters; using typename AdaptiveStepSizeIntegrator::ToleranceToErrorRatio; diff --git "a/integrators/embedded_explicit_runge_kutta_nystr\303\266m_integrator.hpp" "b/integrators/embedded_explicit_runge_kutta_nystr\303\266m_integrator.hpp" index 9b6906627c..56faf5e7ce 100644 --- "a/integrators/embedded_explicit_runge_kutta_nystr\303\266m_integrator.hpp" +++ "b/integrators/embedded_explicit_runge_kutta_nystr\303\266m_integrator.hpp" @@ -68,7 +68,7 @@ class EmbeddedExplicitRungeKuttaNyströmIntegrator : public AdaptiveStepSizeIntegrator { public: using ODE = ODE_; - static_assert(is_instance_of_v); + static_assert(instance_of); using typename Integrator::AppendState; using typename AdaptiveStepSizeIntegrator::Parameters; using typename AdaptiveStepSizeIntegrator::ToleranceToErrorRatio; diff --git a/integrators/explicit_runge_kutta_integrator.hpp b/integrators/explicit_runge_kutta_integrator.hpp index e721fcb869..d657ae3e18 100644 --- a/integrators/explicit_runge_kutta_integrator.hpp +++ b/integrators/explicit_runge_kutta_integrator.hpp @@ -51,8 +51,7 @@ class ExplicitRungeKuttaIntegrator : public FixedStepSizeIntegrator { public: using ODE = ODE_; - static_assert( - is_instance_of_v); + static_assert(instance_of); using typename Integrator::AppendState; static constexpr auto order = Method::order; diff --git a/integrators/integrators_body.hpp b/integrators/integrators_body.hpp index e19a6ffe33..ef2938a412 100644 --- a/integrators/integrators_body.hpp +++ b/integrators/integrators_body.hpp @@ -481,39 +481,37 @@ void FixedStepSizeIntegrator::Instance::WriteToMessage( #define PRINCIPIA_READ_FSS_INTEGRATOR_INSTANCE_ERK(method) LOG(FATAL) << "NYI" -#define PRINCIPIA_READ_FSS_INTEGRATOR_INSTANCE_SLMS(method) \ - if constexpr (is_instance_of_v) { \ - auto const& integrator = \ - SymmetricLinearMultistepIntegrator(); \ - return ReadSlmsInstanceFromMessage( \ - extension, problem, append_state, step, integrator); \ - } else { \ - base::noreturn(); \ +#define PRINCIPIA_READ_FSS_INTEGRATOR_INSTANCE_SLMS(method) \ + if constexpr (instance_of) { \ + auto const& integrator = \ + SymmetricLinearMultistepIntegrator(); \ + return ReadSlmsInstanceFromMessage( \ + extension, problem, append_state, step, integrator); \ + } else { \ + base::noreturn(); \ } -#define PRINCIPIA_READ_FSS_INTEGRATOR_INSTANCE_SPRK(method) \ - if constexpr (is_instance_of_v) { \ - return ReadSprkFromMessage< \ - not_null::Instance>>, \ - ODE, \ - methods::method, \ - methods::method::first_same_as_last>( \ - extension, problem, append_state, step); \ - } else { \ - base::noreturn(); \ +#define PRINCIPIA_READ_FSS_INTEGRATOR_INSTANCE_SPRK(method) \ + if constexpr (instance_of) { \ + return ReadSprkFromMessage< \ + not_null::Instance>>, \ + ODE, \ + methods::method, \ + methods::method::first_same_as_last>( \ + extension, problem, append_state, step); \ + } else { \ + base::noreturn(); \ } -#define PRINCIPIA_READ_FSS_INTEGRATOR_INSTANCE_SRKN(method) \ - if constexpr (is_instance_of_v) { \ - auto const& integrator = \ - SymplecticRungeKuttaNyströmIntegrator(); \ - return ReadSrknInstanceFromMessage( \ - extension, problem, append_state, step, integrator); \ - } else { \ - base::noreturn(); \ +#define PRINCIPIA_READ_FSS_INTEGRATOR_INSTANCE_SRKN(method) \ + if constexpr (instance_of) { \ + auto const& integrator = \ + SymplecticRungeKuttaNyströmIntegrator(); \ + return ReadSrknInstanceFromMessage( \ + extension, problem, append_state, step, integrator); \ + } else { \ + base::noreturn(); \ } template @@ -564,35 +562,32 @@ FixedStepSizeIntegrator::Instance::Instance( CHECK_NE(Time(), step_); } -#define PRINCIPIA_READ_FSS_INTEGRATOR_ELMS(method) \ - if constexpr (is_instance_of_v< \ - ExplicitFirstOrderOrdinaryDifferentialEquation, \ - ODE>) { \ - return ExplicitLinearMultistepIntegrator(); \ - } else { \ - base::noreturn(); \ +#define PRINCIPIA_READ_FSS_INTEGRATOR_ELMS(method) \ + if constexpr (instance_of) { \ + return ExplicitLinearMultistepIntegrator(); \ + } else { \ + base::noreturn(); \ } -#define PRINCIPIA_READ_FSS_INTEGRATOR_ERK(method) \ - if constexpr (is_instance_of_v< \ - ExplicitFirstOrderOrdinaryDifferentialEquation, \ - ODE>) { \ - return ExplicitRungeKuttaIntegrator(); \ - } else { \ - base::noreturn(); \ +#define PRINCIPIA_READ_FSS_INTEGRATOR_ERK(method) \ + if constexpr (instance_of) { \ + return ExplicitRungeKuttaIntegrator(); \ + } else { \ + base::noreturn(); \ } -#define PRINCIPIA_READ_FSS_INTEGRATOR_SLMS(method) \ - if constexpr (is_instance_of_v) { \ - return SymmetricLinearMultistepIntegrator(); \ - } else { \ - base::noreturn(); \ +#define PRINCIPIA_READ_FSS_INTEGRATOR_SLMS(method) \ + if constexpr (instance_of) { \ + return SymmetricLinearMultistepIntegrator(); \ + } else { \ + base::noreturn(); \ } #define PRINCIPIA_READ_FSS_INTEGRATOR_SPRK(method) \ - if constexpr (is_instance_of_v) { \ + if constexpr (instance_of) { \ serialization::FixedStepSizeIntegratorInstance instance; \ *instance.mutable_integrator() = message; \ return ReadSprkFromMessage const&, \ @@ -603,12 +598,11 @@ FixedStepSizeIntegrator::Instance::Instance( base::noreturn(); \ } -#define PRINCIPIA_READ_FSS_INTEGRATOR_SRKN(method) \ - if constexpr (is_instance_of_v) { \ - return SymplecticRungeKuttaNyströmIntegrator(); \ - } else { \ - base::noreturn(); \ +#define PRINCIPIA_READ_FSS_INTEGRATOR_SRKN(method) \ + if constexpr (instance_of) { \ + return SymplecticRungeKuttaNyströmIntegrator(); \ + } else { \ + base::noreturn(); \ } template @@ -717,28 +711,27 @@ void AdaptiveStepSizeIntegrator::Instance::WriteToMessage( integrator().WriteToMessage(extension->mutable_integrator()); } -#define PRINCIPIA_READ_ASS_INTEGRATOR_INSTANCE_EEGRKN(method) \ - if constexpr (is_instance_of_v< \ - ExplicitSecondOrderOrdinaryDifferentialEquation, \ - ODE>) { \ - auto const& integrator = \ - EmbeddedExplicitGeneralizedRungeKuttaNyströmIntegrator< \ - methods::method, \ - ODE>(); \ - return ReadEegrknInstanceFromMessage(extension, \ - problem, \ - append_state, \ - tolerance_to_error_ratio, \ - parameters, \ - step, \ - first_use, \ - integrator); \ - } else { \ - base::noreturn(); \ +#define PRINCIPIA_READ_ASS_INTEGRATOR_INSTANCE_EEGRKN(method) \ + if constexpr (instance_of< \ + ODE, \ + ExplicitSecondOrderOrdinaryDifferentialEquation>) { \ + auto const& integrator = \ + EmbeddedExplicitGeneralizedRungeKuttaNyströmIntegrator< \ + methods::method, \ + ODE>(); \ + return ReadEegrknInstanceFromMessage(extension, \ + problem, \ + append_state, \ + tolerance_to_error_ratio, \ + parameters, \ + step, \ + first_use, \ + integrator); \ + } else { \ + base::noreturn(); \ } #define PRINCIPIA_READ_ASS_INTEGRATOR_INSTANCE_EERKN(method) \ - if constexpr (is_instance_of_v) { \ + if constexpr (instance_of) { \ auto const& integrator = \ EmbeddedExplicitRungeKuttaNyströmIntegrator(); \ return ReadEerknInstanceFromMessage(extension, \ @@ -831,24 +824,23 @@ AdaptiveStepSizeIntegrator::Instance::Instance( CHECK_LT(parameters.safety_factor, 1); } -#define PRINCIPIA_READ_ASS_INTEGRATOR_EEGRKN(method) \ - if constexpr (is_instance_of_v< \ - ExplicitSecondOrderOrdinaryDifferentialEquation, \ - ODE>) { \ - return EmbeddedExplicitGeneralizedRungeKuttaNyströmIntegrator< \ - methods::method, \ - ODE>(); \ - } else { \ - base::noreturn(); \ +#define PRINCIPIA_READ_ASS_INTEGRATOR_EEGRKN(method) \ + if constexpr (instance_of< \ + ODE, \ + ExplicitSecondOrderOrdinaryDifferentialEquation>) { \ + return EmbeddedExplicitGeneralizedRungeKuttaNyströmIntegrator< \ + methods::method, \ + ODE>(); \ + } else { \ + base::noreturn(); \ } -#define PRINCIPIA_READ_ASS_INTEGRATOR_EERKN(method) \ - if constexpr (is_instance_of_v) { \ - return EmbeddedExplicitRungeKuttaNyströmIntegrator(); \ - } else { \ - base::noreturn(); \ +#define PRINCIPIA_READ_ASS_INTEGRATOR_EERKN(method) \ + if constexpr (instance_of) { \ + return EmbeddedExplicitRungeKuttaNyströmIntegrator(); \ + } else { \ + base::noreturn(); \ } #define PRINCIPIA_READ_ASS_INTEGRATOR_EERK(method) LOG(FATAL) << "NYI" diff --git a/integrators/symmetric_linear_multistep_integrator.hpp b/integrators/symmetric_linear_multistep_integrator.hpp index 48853174b7..f855859bb3 100644 --- a/integrators/symmetric_linear_multistep_integrator.hpp +++ b/integrators/symmetric_linear_multistep_integrator.hpp @@ -45,7 +45,7 @@ class SymmetricLinearMultistepIntegrator : public FixedStepSizeIntegrator { public: using ODE = ODE_; - static_assert(is_instance_of_v); + static_assert(instance_of); using AppendState = typename Integrator::AppendState; static constexpr int order = Method::order; diff --git a/integrators/symplectic_partitioned_runge_kutta_integrator.hpp b/integrators/symplectic_partitioned_runge_kutta_integrator.hpp index 504af17b46..27ed845ff3 100644 --- a/integrators/symplectic_partitioned_runge_kutta_integrator.hpp +++ b/integrators/symplectic_partitioned_runge_kutta_integrator.hpp @@ -57,8 +57,7 @@ class SymplecticPartitionedRungeKuttaIntegrator : public FixedStepSizeIntegrator { public: using ODE = ODE_; - static_assert( - is_instance_of_v); + static_assert(instance_of); using AppendState = typename Integrator::AppendState; static constexpr auto time_reversible = Method::time_reversible; diff --git "a/integrators/symplectic_runge_kutta_nystr\303\266m_integrator.hpp" "b/integrators/symplectic_runge_kutta_nystr\303\266m_integrator.hpp" index 7259860c10..c38fdde016 100644 --- "a/integrators/symplectic_runge_kutta_nystr\303\266m_integrator.hpp" +++ "b/integrators/symplectic_runge_kutta_nystr\303\266m_integrator.hpp" @@ -75,7 +75,7 @@ class SymplecticRungeKuttaNyströmIntegrator : public FixedStepSizeIntegrator { public: using ODE = ODE_; - static_assert(is_instance_of_v); + static_assert(instance_of); using AppendState = typename Integrator::AppendState; static constexpr auto order = Method::order; diff --git a/mathematica/mathematica_body.hpp b/mathematica/mathematica_body.hpp index 0d0cf20191..d3696334ee 100644 --- a/mathematica/mathematica_body.hpp +++ b/mathematica/mathematica_body.hpp @@ -98,7 +98,7 @@ std::string ToMathematicaBody( coefficients, express_in); std::string argument; - if constexpr (is_instance_of_v) { + if constexpr (instance_of) { argument = RawApply("Subtract", {"#", ToMathematica(polynomial.origin_, express_in)}); } else { diff --git "a/numerics/polynomial_in_\321\207\320\265\320\261\321\213\321\210\321\221\320\262_basis_body.hpp" "b/numerics/polynomial_in_\321\207\320\265\320\261\321\213\321\210\321\221\320\262_basis_body.hpp" index a232511540..184ad6f66f 100644 --- "a/numerics/polynomial_in_\321\207\320\265\320\261\321\213\321\210\321\221\320\262_basis_body.hpp" +++ "b/numerics/polynomial_in_\321\207\320\265\320\261\321\213\321\210\321\221\320\262_basis_body.hpp" @@ -245,7 +245,7 @@ PolynomialInЧебышёвBasis::FrobeniusCompanionM template void PolynomialInЧебышёвBasis::WriteToMessage( not_null message) const { - if constexpr (is_instance_of_v) { + if constexpr (instance_of) { // |R3Element| is a low-level structure, so we don't want polynomials to use // it directly: they should go through |Multivector|. However, it's useful // to be able to run benchmarks using them.