1 #ifndef STAN_MATH_PRIM_META_IS_CONSTANT_HPP
2 #define STAN_MATH_PRIM_META_IS_CONSTANT_HPP
3 
4 #include <stan/math/prim/fun/Eigen.hpp>
5 #include <stan/math/prim/meta/bool_constant.hpp>
6 #include <stan/math/prim/meta/conjunction.hpp>
7 #include <stan/math/prim/meta/is_vector.hpp>
8 #include <stan/math/prim/meta/is_eigen.hpp>
9 #include <stan/math/prim/meta/scalar_type.hpp>
10 #include <stan/math/prim/meta/value_type.hpp>
11 #include <stan/math/prim/meta/require_generics.hpp>
12 #include <type_traits>
13 #include <vector>
14 namespace stan {
15 
16 /** \ingroup type_trait
17  * Metaprogramming struct to detect whether a given type is constant
18  * in the mathematical sense (not the C++ <code>const</code>
19  * sense). If the parameter type is constant, <code>value</code>
20  * will be equal to <code>true</code>.
21  *
22  * The baseline implementation in this abstract base class is to
23  * classify a type <code>T</code> as constant if it can be converted
24  * (i.e., assigned) to a <code>double</code>.  This baseline should
25  * be overridden for any type that should be treated as a variable.
26  *
27  * @tparam T Type being tested.
28  */
29 template <typename T, typename = void>
30 struct is_constant : bool_constant<std::is_convertible<T, double>::value> {};
31 
32 /** \ingroup type_trait
33  * Metaprogram defining an enum <code>value</code> which
34  * is <code>true</code> if all of the type parameters
35  * are constant (i.e., primitive types) and
36  * <code>false</code> otherwise.
37  */
38 template <typename... T>
39 using is_constant_all = math::conjunction<is_constant<T>...>;
40 
41 /** \ingroup type_trait
42  * Defines a static member named value and sets it to true
43  * if the type of the elements in the provided std::vector
44  * is constant, false otherwise. This is used in
45  * the is_constant_all metaprogram.
46  * @tparam type of the elements in the std::vector
47  */
48 template <typename T>
49 struct is_constant<T, require_std_vector_t<T>>
50     : bool_constant<is_constant<typename std::decay_t<T>::value_type>::value> {
51 };
52 
53 /** \ingroup type_trait
54  * Defines a public enum named value and sets it to true
55  * if the type of the elements in the provided Eigen Matrix
56  * is constant, false otherwise. This is used in
57  * the is_constant_all metaprogram.
58  *
59  * @tparam T type of the Eigen Matrix
60  */
61 template <typename T>
62 struct is_constant<T, require_eigen_t<T>>
63     : bool_constant<is_constant<typename std::decay_t<T>::Scalar>::value> {};
64 
65 STAN_ADD_REQUIRE_UNARY(constant, is_constant, require_stan_scalar_real);
66 STAN_ADD_REQUIRE_UNARY_INNER(constant, is_constant, require_stan_scalar_real);
67 
68 }  // namespace stan
69 #endif
70