diff --git a/include/ceres/internal/integer_sequence_algorithm.h b/include/ceres/internal/integer_sequence_algorithm.h index 777c119a7..80c821c5c 100644 --- a/include/ceres/internal/integer_sequence_algorithm.h +++ b/include/ceres/internal/integer_sequence_algorithm.h @@ -43,68 +43,6 @@ namespace ceres { namespace internal { -// Implementation of calculating the sum of an integer sequence. -// Recursively instantiate SumImpl and calculate the sum of the N first -// numbers. This reduces the number of instantiations and speeds up -// compilation. -// -// Examples: -// 1) integer_sequence: -// Value = 5 -// -// 2) integer_sequence: -// Value = 4 + 2 + SumImpl>::Value -// Value = 4 + 2 + 0 -// -// 3) integer_sequence: -// Value = 2 + 1 + SumImpl>::Value -// Value = 2 + 1 + 4 -template -struct SumImpl; - -// Strip of and sum the first number. -template -struct SumImpl> { - static constexpr T Value = - N + SumImpl>::Value; -}; - -// Strip of and sum the first two numbers. -template -struct SumImpl> { - static constexpr T Value = - N1 + N2 + SumImpl>::Value; -}; - -// Strip of and sum the first four numbers. -template -struct SumImpl> { - static constexpr T Value = - N1 + N2 + N3 + N4 + SumImpl>::Value; -}; - -// Only one number is left. 'Value' is just that number ('recursion' ends). -template -struct SumImpl> { - static constexpr T Value = N; -}; - -// No number is left. 'Value' is the identity element (for sum this is zero). -template -struct SumImpl> { - static constexpr T Value = T(0); -}; - -// Calculate the sum of an integer sequence. The resulting sum will be stored in -// 'Value'. -template -class Sum { - using T = typename Seq::value_type; - - public: - static constexpr T Value = SumImpl::Value; -}; - // Implementation of calculating an exclusive scan (exclusive prefix sum) of an // integer sequence. Exclusive means that the i-th input element is not included // in the i-th sum. Calculating the exclusive scan for an input array I results @@ -232,40 +170,11 @@ struct RemoveValue template using RemoveValue_t = typename RemoveValue::type; -// Determines whether the values of an integer sequence are all the same. +// Returns true if all elements of Values are equal to HeadValue. // -// The integer sequence must contain at least one value. The predicate is -// undefined for empty sequences. The evaluation result of the predicate for a -// sequence containing only one value is defined to be true. -template -struct AreAllEqual; - -// The predicate result for a sequence containing one element is defined to be -// true. -template -struct AreAllEqual> : std::true_type {}; - -// Recursion end. -template -struct AreAllEqual> - : std::integral_constant {}; - -// Recursion for sequences containing at least two elements. -template -// clang-format off -struct AreAllEqual > - : std::integral_constant -< - bool, - AreAllEqual >::value && - AreAllEqual >::value -> -// clang-format on -{}; - -// Convenience variable template for AreAllEqual. -template -constexpr bool AreAllEqual_v = AreAllEqual::value; +// Returns true if Values is empty. +template +inline constexpr bool AreAllEqual_v = ((HeadValue == Values) && ...); // Predicate determining whether an integer sequence is either empty or all // values are equal. @@ -279,11 +188,12 @@ struct IsEmptyOrAreAllEqual> : std::true_type {}; // General case for sequences containing at least one value. template struct IsEmptyOrAreAllEqual> - : AreAllEqual> {}; + : std::integral_constant> {}; // Convenience variable template for IsEmptyOrAreAllEqual. template -constexpr bool IsEmptyOrAreAllEqual_v = IsEmptyOrAreAllEqual::value; +inline constexpr bool IsEmptyOrAreAllEqual_v = + IsEmptyOrAreAllEqual::value; } // namespace internal } // namespace ceres diff --git a/include/ceres/internal/jet_traits.h b/include/ceres/internal/jet_traits.h index 2a38c05b7..746638f9f 100644 --- a/include/ceres/internal/jet_traits.h +++ b/include/ceres/internal/jet_traits.h @@ -42,17 +42,6 @@ namespace ceres { namespace internal { -// Predicate that determines whether T is a Jet. -template -struct IsJet : std::false_type {}; - -template -struct IsJet> : std::true_type {}; - -// Convenience variable template for IsJet. -template -constexpr bool IsJet_v = IsJet::value; - // Predicate that determines whether any of the Types is a Jet. template struct AreAnyJet : std::false_type {}; @@ -65,7 +54,7 @@ struct AreAnyJet, Types...> : std::true_type {}; // Convenience variable template for AreAnyJet. template -constexpr bool AreAnyJet_v = AreAnyJet::value; +inline constexpr bool AreAnyJet_v = AreAnyJet::value; // Extracts the underlying floating-point from a type T. template @@ -84,27 +73,8 @@ using UnderlyingScalar_t = typename UnderlyingScalar::type; // // Specifically, the predicate applies std::is_same recursively to pairs of // Types in the pack. -// -// The predicate is defined only for template packs containing at least two -// types. -template -// clang-format off -struct AreAllSame : std::integral_constant -< - bool, - AreAllSame::value && - AreAllSame::value -> -// clang-format on -{}; - -// AreAllSame pairwise test. -template -struct AreAllSame : std::is_same {}; - -// Convenience variable template for AreAllSame. -template -constexpr bool AreAllSame_v = AreAllSame::value; +template +inline constexpr bool AreAllSame_v = (std::is_same::value && ...); // Determines the rank of a type. This allows to ensure that types passed as // arguments are compatible to each other. The rank of Jet is determined by the @@ -124,7 +94,7 @@ struct Rank> : std::integral_constant {}; // Convenience variable template for Rank. template -constexpr int Rank_v = Rank::value; +inline constexpr int Rank_v = Rank::value; // Constructs an integer sequence of ranks for each of the Types in the pack. template @@ -186,7 +156,8 @@ struct CompatibleJetOperands<> : std::false_type {}; // This trait is a candidate for a concept definition once C++20 features can // be used. template -constexpr bool CompatibleJetOperands_v = CompatibleJetOperands::value; +inline constexpr bool CompatibleJetOperands_v = + CompatibleJetOperands::value; // Type trait ensuring at least one of the types is a Jet, // the underlying scalar types are compatible among each other and Jet @@ -216,7 +187,8 @@ struct PromotableJetOperands : std::integral_constant // This trait is a candidate for a concept definition once C++20 features can // be used. template -constexpr bool PromotableJetOperands_v = PromotableJetOperands::value; +inline constexpr bool PromotableJetOperands_v = + PromotableJetOperands::value; } // namespace ceres diff --git a/include/ceres/internal/parameter_dims.h b/include/ceres/internal/parameter_dims.h index 240210614..efe2df4d3 100644 --- a/include/ceres/internal/parameter_dims.h +++ b/include/ceres/internal/parameter_dims.h @@ -39,20 +39,6 @@ namespace ceres { namespace internal { -// Checks, whether the given parameter block sizes are valid. Valid means every -// dimension is bigger than zero. -constexpr bool IsValidParameterDimensionSequence(std::integer_sequence) { - return true; -} - -template -constexpr bool IsValidParameterDimensionSequence( - std::integer_sequence) { - return (N <= 0) ? false - : IsValidParameterDimensionSequence( - std::integer_sequence()); -} - // Helper class that represents the parameter dimensions. The parameter // dimensions are either dynamic or the sizes are known at compile time. It is // used to pass parameter block dimensions around (e.g. between functions or @@ -70,8 +56,7 @@ class ParameterDims { // The parameter dimensions are only valid if all parameter block dimensions // are greater than zero. - static constexpr bool kIsValid = - IsValidParameterDimensionSequence(Parameters()); + static constexpr bool kIsValid = ((Ns > 0) && ...); static_assert(kIsValid, "Invalid parameter block dimension detected. Each parameter " "block dimension must be bigger than zero."); @@ -81,8 +66,7 @@ class ParameterDims { static_assert(kIsDynamic || kNumParameterBlocks > 0, "At least one parameter block must be specified."); - static constexpr int kNumParameters = - Sum>::Value; + static constexpr int kNumParameters = (Ns + ... + 0); static constexpr int GetDim(int dim) { return params_[dim]; } diff --git a/internal/ceres/integer_sequence_algorithm_test.cc b/internal/ceres/integer_sequence_algorithm_test.cc index 7e041486c..4622feaa4 100644 --- a/internal/ceres/integer_sequence_algorithm_test.cc +++ b/internal/ceres/integer_sequence_algorithm_test.cc @@ -39,20 +39,6 @@ namespace ceres { namespace internal { -// Unit tests for summation of integer sequence. -static_assert(Sum>::Value == 0, - "Unit test of summing up an integer sequence failed."); -static_assert(Sum>::Value == 2, - "Unit test of summing up an integer sequence failed."); -static_assert(Sum>::Value == 5, - "Unit test of summing up an integer sequence failed."); -static_assert(Sum>::Value == 15, - "Unit test of summing up an integer sequence failed."); -static_assert(Sum>::Value == 19, - "Unit test of summing up an integer sequence failed."); -static_assert(Sum>::Value == 20, - "Unit test of summing up an integer sequence failed."); - // Unit tests for exclusive scan of integer sequence. static_assert(std::is_same>, std::integer_sequence>::value, @@ -129,15 +115,15 @@ static_assert(!AreAllSame_v, "types must not be the same"); static_assert(!AreAllSame_v, "types must not be the same"); // Ensure all values in the integer sequence match -static_assert(AreAllEqual_v>, +static_assert(AreAllEqual_v, "integer sequence must contain same values"); -static_assert(AreAllEqual_v>, +static_assert(AreAllEqual_v, "integer sequence must contain one value"); -static_assert(!AreAllEqual_v>, +static_assert(!AreAllEqual_v, "integer sequence must not contain the same values"); -static_assert(!AreAllEqual_v>, +static_assert(!AreAllEqual_v, "integer sequence must not contain the same values"); -static_assert(!AreAllEqual_v>, +static_assert(!AreAllEqual_v, "integer sequence must not contain the same values"); static_assert(IsEmptyOrAreAllEqual_v>, diff --git a/internal/ceres/jet_traits_test.cc b/internal/ceres/jet_traits_test.cc index ee38f4712..43afc3ccb 100644 --- a/internal/ceres/jet_traits_test.cc +++ b/internal/ceres/jet_traits_test.cc @@ -44,20 +44,6 @@ template using J0 = Jet; using J0d = J0; -struct NotAJet {}; - -static_assert(IsJet_v, "Jet is not identified as one"); -static_assert(IsJet_v>, "Jet is not identified as one"); -static_assert(IsJet_v>, "nested Jet is not identified as one"); -static_assert(IsJet_v>>, "nested Jet is not identified as one"); - -static_assert(!IsJet_v, "double must not be a Jet"); -static_assert(!IsJet_v, "Eigen::VectorXd must not be a Jet"); -static_assert(!IsJet_v() * - std::declval())>, - "product of Eigen::MatrixXd must not be a Jet"); -static_assert(!IsJet_v, "NotAJet must not be a Jet"); - // Extract the ranks of given types using Ranks001 = Ranks_t, double, Jet>; using Ranks1 = Ranks_t>; diff --git a/internal/ceres/parameter_dims_test.cc b/internal/ceres/parameter_dims_test.cc index ee3be8fa0..58d2500fa 100644 --- a/internal/ceres/parameter_dims_test.cc +++ b/internal/ceres/parameter_dims_test.cc @@ -32,20 +32,6 @@ namespace ceres { namespace internal { -// Is valid parameter dims unit test -static_assert(IsValidParameterDimensionSequence(std::integer_sequence()) == - true, - "Unit test of is valid parameter dimension sequence failed."); -static_assert(IsValidParameterDimensionSequence( - std::integer_sequence()) == true, - "Unit test of is valid parameter dimension sequence failed."); -static_assert(IsValidParameterDimensionSequence( - std::integer_sequence()) == false, - "Unit test of is valid parameter dimension sequence failed."); -static_assert(IsValidParameterDimensionSequence( - std::integer_sequence()) == false, - "Unit test of is valid parameter dimension sequence failed."); - // Static parameter dims unit test static_assert( std::is_same::Parameters, diff --git a/internal/ceres/program_test.cc b/internal/ceres/program_test.cc index 8dc1377b0..300a3a54c 100644 --- a/internal/ceres/program_test.cc +++ b/internal/ceres/program_test.cc @@ -70,7 +70,7 @@ class MockCostFunctionBase : public SizedCostFunction { bool Evaluate(double const* const* parameters, double* residuals, double** jacobians) const final { - const int kNumParameters = Sum>::Value; + constexpr int kNumParameters = (Ns + ... + 0); for (int i = 0; i < kNumResiduals; ++i) { residuals[i] = kNumResiduals + kNumParameters;