// Ceres Solver - A fast non-linear least squares minimizer // Copyright 2023 Google Inc. All rights reserved. // http://ceres-solver.org/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither the name of Google Inc. nor the names of its contributors may be // used to endorse or promote products derived from this software without // specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // // Author: sergiu.deitsch@gmail.com (Sergiu Deitsch) // #ifndef CERES_PUBLIC_INTERNAL_JET_TRAITS_H_ #define CERES_PUBLIC_INTERNAL_JET_TRAITS_H_ #include #include #include #include "ceres/internal/integer_sequence_algorithm.h" #include "ceres/jet_fwd.h" namespace ceres { namespace internal { // Predicate that determines whether any of the Types is a Jet. template struct AreAnyJet : std::false_type {}; template struct AreAnyJet : AreAnyJet {}; template struct AreAnyJet, Types...> : std::true_type {}; // Convenience variable template for AreAnyJet. template inline constexpr bool AreAnyJet_v = AreAnyJet::value; // Extracts the underlying floating-point from a type T. template struct UnderlyingScalar { using type = T; }; template struct UnderlyingScalar> : UnderlyingScalar {}; // Convenience template alias for UnderlyingScalar type trait. template using UnderlyingScalar_t = typename UnderlyingScalar::type; // Predicate determining whether all Types in the pack are the same. // // Specifically, the predicate applies std::is_same recursively to pairs of // Types in the pack. 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 // dimensions of the dual part. The rank of a scalar is always 0. // Non-specialized types default to a rank of -1. template struct Rank : std::integral_constant {}; // The rank of a scalar is 0. template struct Rank::value>> : std::integral_constant {}; // The rank of a Jet is given by its dimensionality. template struct Rank> : std::integral_constant {}; // Convenience variable template for Rank. template inline constexpr int Rank_v = Rank::value; // Constructs an integer sequence of ranks for each of the Types in the pack. template using Ranks_t = std::integer_sequence...>; // Returns the scalar part of a type. This overload acts as an identity. template constexpr decltype(auto) AsScalar(T&& value) noexcept { return std::forward(value); } // Recursively unwraps the scalar part of a Jet until a non-Jet scalar type is // encountered. template constexpr decltype(auto) AsScalar(const Jet& value) noexcept( noexcept(AsScalar(value.a))) { return AsScalar(value.a); } } // namespace internal // Type trait ensuring at least one of the types is a Jet, // the underlying scalar types are the same and Jet dimensions match. // // The type trait can be further specialized if necessary. // // This trait is a candidate for a concept definition once C++20 features can // be used. template // clang-format off struct CompatibleJetOperands : std::integral_constant < bool, // At least one of the types is a Jet internal::AreAnyJet_v && // The underlying floating-point types are exactly the same internal::AreAllSame_v...> && // Non-zero ranks of types are equal internal::IsEmptyOrAreAllEqual_v, 0>> > // clang-format on {}; // Single Jet operand is always compatible. template struct CompatibleJetOperands> : std::true_type {}; // Single non-Jet operand is always incompatible. template struct CompatibleJetOperands : std::false_type {}; // Empty operands are always incompatible. template <> struct CompatibleJetOperands<> : std::false_type {}; // Convenience variable template ensuring at least one of the types is a Jet, // the underlying scalar types are the same and Jet dimensions match. // // This trait is a candidate for a concept definition once C++20 features can // be used. template 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 // dimensions match. // // The type trait can be further specialized if necessary. // // This trait is a candidate for a concept definition once C++20 features can // be used. template // clang-format off struct PromotableJetOperands : std::integral_constant < bool, // Types can be compatible among each other internal::AreAnyJet_v && // Non-zero ranks of types are equal internal::IsEmptyOrAreAllEqual_v, 0>> > // clang-format on {}; // Convenience variable template ensuring at least one of the types is a Jet, // the underlying scalar types are compatible among each other and Jet // dimensions match. // // This trait is a candidate for a concept definition once C++20 features can // be used. template inline constexpr bool PromotableJetOperands_v = PromotableJetOperands::value; } // namespace ceres #endif // CERES_PUBLIC_INTERNAL_JET_TRAITS_H_