@@ -54,12 +54,38 @@ inline T_actual&& forward_as(T_actual&& a) { // NOLINT
5454 * @return nothing, this always throws
5555 * @throw always throws std::runtime_error
5656 */
57+ template <
58+ typename T_desired, typename T_actual,
59+ require_any_not_eigen_t <T_desired, T_actual>* = nullptr ,
60+ typename = std::enable_if_t <
61+ !std::is_same<std::decay<T_actual>, std::decay<T_desired>>::value
62+ && !(std::is_floating_point_v<std::decay_t <
63+ T_desired>> && std::is_integral_v<std::decay_t <T_actual>>)>>
64+ inline T_desired forward_as (const T_actual& a) {
65+ throw std::runtime_error (" Wrong type assumed! Please file a bug report." );
66+ }
67+
68+ /* * \ingroup type_trait
69+ * Assume which type we get. If actual type is not convertible to assumed type
70+ * or in case of eigen types compile time rows and columns are not the same and
71+ * desired sizes are not dynamic this has return type of \c T_desired, but it
72+ * only throws. This version should only be used where it is optimized away so
73+ * the throw should never happen.
74+ *
75+ * This handles the edge case where both types are simple arithmetic types
76+ * and we would like to just convert one to another.
77+ *
78+ * @tparam T_desired type of output we need to avoid compile time errors
79+ * @tparam T_actual actual type of the argument
80+ * @param a input value
81+ * @return a
82+ */
5783template <typename T_desired, typename T_actual,
5884 typename = std::enable_if_t <
59- ! std::is_same <std::decay<T_actual>, std::decay<T_desired>>::value
60- && (!is_eigen<T_desired>::value || !is_eigen <T_actual>::value) >>
85+ std::is_floating_point_v <std::decay_t <
86+ T_desired>> && std::is_integral_v<std:: decay_t <T_actual>> >>
6187inline T_desired forward_as (const T_actual& a) {
62- throw std::runtime_error ( " Wrong type assumed! Please file a bug report. " );
88+ return static_cast <T_desired>(a );
6389}
6490
6591/* * \ingroup type_trait
0 commit comments