1#ifndef STAN_MATH_PRIM_FUN_PROMOTE_SCALAR_HPP
2#define STAN_MATH_PRIM_FUN_PROMOTE_SCALAR_HPP
14template <
typename PromotionScalars,
typename UnPromotedTypes>
17 constexpr bool both_tuples
18 = is_tuple_v<PromotionScalars> && is_tuple_v<UnPromotedTypes>;
19 if constexpr (std::is_same_v<PromotionScalars, unpromoted_scalar_t>) {
20 return std::forward<UnPromotedTypes>(x);
21 }
else if constexpr (both_tuples) {
22 return index_apply<std::tuple_size<std::decay_t<UnPromotedTypes>>::value>(
24 return std::make_tuple(
26 std::declval<PromotionScalars>()))>>(std::get<Is>(x))...);
28 }
else if constexpr (is_tuple_v<UnPromotedTypes>) {
31 return std::make_tuple(promote_scalar<PromotionScalars>(
32 std::forward<
decltype(args)>(args))...);
34 std::forward<UnPromotedTypes>(x));
35 }
else if constexpr (is_std_vector_v<UnPromotedTypes>) {
36 const auto x_size = x.size();
38 for (
size_t i = 0; i < x_size; ++i) {
39 ret[i] = promote_scalar<PromotionScalars>(x[i]);
42 }
else if constexpr (is_eigen_v<UnPromotedTypes>) {
43 return std::forward<UnPromotedTypes>(x).template cast<PromotionScalars>();
44 }
else if constexpr (is_stan_scalar_v<UnPromotedTypes>) {
45 return PromotionScalars(std::forward<UnPromotedTypes>(x));
47 static_assert(
sizeof(std::decay_t<UnPromotedTypes>*) == 0,
48 "INTERNAL ERROR:(promote_scalar) "
49 "Unrecognized type for promotion. "
50 "This is an internal error, please report it: "
51 "https://github.com/stan-dev/math/issues");
constexpr auto promote_scalar(UnPromotedTypes &&x)
typename promote_scalar_type< std::decay_t< T >, std::decay_t< S > >::type promote_scalar_t
constexpr decltype(auto) apply(F &&f, Tuple &&t, PreArgs &&... pre_args)
typename scalar_type< T >::type scalar_type_t
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...