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