123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- // 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 <tuple>
- #include <type_traits>
- #include <utility>
- #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 <typename... Types>
- struct AreAnyJet : std::false_type {};
- template <typename T, typename... Types>
- struct AreAnyJet<T, Types...> : AreAnyJet<Types...> {};
- template <typename T, int N, typename... Types>
- struct AreAnyJet<Jet<T, N>, Types...> : std::true_type {};
- // Convenience variable template for AreAnyJet.
- template <typename... Types>
- inline constexpr bool AreAnyJet_v = AreAnyJet<Types...>::value;
- // Extracts the underlying floating-point from a type T.
- template <typename T, typename E = void>
- struct UnderlyingScalar {
- using type = T;
- };
- template <typename T, int N>
- struct UnderlyingScalar<Jet<T, N>> : UnderlyingScalar<T> {};
- // Convenience template alias for UnderlyingScalar type trait.
- template <typename T>
- using UnderlyingScalar_t = typename UnderlyingScalar<T>::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 <typename T1, typename... Types>
- inline constexpr bool AreAllSame_v = (std::is_same<T1, Types>::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 <typename T, typename E = void>
- struct Rank : std::integral_constant<int, -1> {};
- // The rank of a scalar is 0.
- template <typename T>
- struct Rank<T, std::enable_if_t<std::is_scalar<T>::value>>
- : std::integral_constant<int, 0> {};
- // The rank of a Jet is given by its dimensionality.
- template <typename T, int N>
- struct Rank<Jet<T, N>> : std::integral_constant<int, N> {};
- // Convenience variable template for Rank.
- template <typename T>
- inline constexpr int Rank_v = Rank<T>::value;
- // Constructs an integer sequence of ranks for each of the Types in the pack.
- template <typename... Types>
- using Ranks_t = std::integer_sequence<int, Rank_v<Types>...>;
- // Returns the scalar part of a type. This overload acts as an identity.
- template <typename T>
- constexpr decltype(auto) AsScalar(T&& value) noexcept {
- return std::forward<T>(value);
- }
- // Recursively unwraps the scalar part of a Jet until a non-Jet scalar type is
- // encountered.
- template <typename T, int N>
- constexpr decltype(auto) AsScalar(const Jet<T, N>& 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 <typename... Types>
- // clang-format off
- struct CompatibleJetOperands : std::integral_constant
- <
- bool,
- // At least one of the types is a Jet
- internal::AreAnyJet_v<Types...> &&
- // The underlying floating-point types are exactly the same
- internal::AreAllSame_v<internal::UnderlyingScalar_t<Types>...> &&
- // Non-zero ranks of types are equal
- internal::IsEmptyOrAreAllEqual_v<internal::RemoveValue_t<internal::Ranks_t<Types...>, 0>>
- >
- // clang-format on
- {};
- // Single Jet operand is always compatible.
- template <typename T, int N>
- struct CompatibleJetOperands<Jet<T, N>> : std::true_type {};
- // Single non-Jet operand is always incompatible.
- template <typename T>
- struct CompatibleJetOperands<T> : 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 <typename... Types>
- inline constexpr bool CompatibleJetOperands_v =
- CompatibleJetOperands<Types...>::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 <typename... Types>
- // clang-format off
- struct PromotableJetOperands : std::integral_constant
- <
- bool,
- // Types can be compatible among each other
- internal::AreAnyJet_v<Types...> &&
- // Non-zero ranks of types are equal
- internal::IsEmptyOrAreAllEqual_v<internal::RemoveValue_t<internal::Ranks_t<Types...>, 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 <typename... Types>
- inline constexpr bool PromotableJetOperands_v =
- PromotableJetOperands<Types...>::value;
- } // namespace ceres
- #endif // CERES_PUBLIC_INTERNAL_JET_TRAITS_H_
|