1 #ifndef STAN_MATH_PRIM_FUN_VALUE_OF_HPP
2 #define STAN_MATH_PRIM_FUN_VALUE_OF_HPP
3
4 #include <stan/math/prim/meta.hpp>
5 #include <stan/math/prim/fun/Eigen.hpp>
6 #include <cstddef>
7 #include <vector>
8
9 namespace stan {
10 namespace math {
11
12 /**
13 * Inputs that are arithmetic types or containers of airthmetric types
14 * are returned from value_of unchanged
15 *
16 * @tparam T Input type
17 * @param[in] x Input argument
18 * @return Forwarded input argument
19 **/
20 template <typename T, require_st_arithmetic<T>* = nullptr>
value_of(T && x)21 inline T value_of(T&& x) {
22 return std::forward<T>(x);
23 }
24
25 template <typename T, require_complex_t<T>* = nullptr,
26 require_t<std::is_arithmetic<
27 typename std::decay_t<T>::value_type>>* = nullptr>
value_of(T && x)28 inline auto value_of(T&& x) {
29 return std::forward<T>(x);
30 }
31
32 template <
33 typename T, require_complex_t<T>* = nullptr,
34 require_not_arithmetic_t<typename std::decay_t<T>::value_type>* = nullptr>
value_of(T && x)35 inline auto value_of(T&& x) {
36 using inner_t = partials_type_t<typename std::decay_t<T>::value_type>;
37 return std::complex<inner_t>{value_of(x.real()), value_of(x.imag())};
38 }
39
40 /**
41 * For std::vectors of non-arithmetic types, return a std::vector composed
42 * of value_of applied to each element.
43 *
44 * @tparam T Input element type
45 * @param[in] x Input std::vector
46 * @return std::vector of values
47 **/
48 template <typename T, require_std_vector_t<T>* = nullptr,
49 require_not_st_arithmetic<T>* = nullptr>
value_of(const T & x)50 inline auto value_of(const T& x) {
51 std::vector<plain_type_t<decltype(value_of(std::declval<value_type_t<T>>()))>>
52 out;
53 out.reserve(x.size());
54 for (auto&& x_elem : x) {
55 out.emplace_back(value_of(x_elem));
56 }
57 return out;
58 }
59
60 /**
61 * For Eigen matrices and expressions of non-arithmetic types, return an
62 *expression that represents the Eigen::Matrix resulting from applying value_of
63 *elementwise
64 *
65 * @tparam EigMat type of the matrix
66 *
67 * @param[in] M Matrix to be converted
68 * @return Matrix of values
69 **/
70 template <typename EigMat, require_eigen_t<EigMat>* = nullptr,
71 require_not_st_arithmetic<EigMat>* = nullptr>
value_of(EigMat && M)72 inline auto value_of(EigMat&& M) {
73 return make_holder(
74 [](auto& a) {
75 return a.unaryExpr([](const auto& scal) { return value_of(scal); });
76 },
77 std::forward<EigMat>(M));
78 }
79
80 } // namespace math
81 } // namespace stan
82
83 #endif
84