1 #ifndef STAN_MATH_PRIM_META_REQUIRE_HELPERS_HPP 2 #define STAN_MATH_PRIM_META_REQUIRE_HELPERS_HPP 3 4 #include <stan/math/prim/meta/conjunction.hpp> 5 #include <stan/math/prim/meta/disjunction.hpp> 6 #include <stan/math/prim/meta/bool_constant.hpp> 7 #include <stan/math/prim/meta/scalar_type.hpp> 8 #include <stan/math/prim/meta/value_type.hpp> 9 10 #include <type_traits> 11 12 namespace stan { 13 14 /** 15 * If condition is true, template is enabled 16 * @ingroup type_traits 17 */ 18 template <class Check> 19 using require_t = std::enable_if_t<Check::value>; 20 21 /** 22 * If condition is false, template is disabled 23 * @ingroup type_traits 24 */ 25 template <typename Check> 26 using require_not_t = std::enable_if_t<!Check::value>; 27 28 /** 29 * If all conditions are true, template is enabled 30 * Returns a type void if all conditions are true and otherwise fails. 31 * @ingroup type_traits 32 */ 33 template <class... Checks> 34 using require_all_t = std::enable_if_t<math::conjunction<Checks...>::value>; 35 36 /** 37 * If any condition is true, template is enabled. 38 * 39 * Returns a type void if any of the conditions are true and otherwise fails. 40 * @ingroup type_traits 41 */ 42 template <class... Checks> 43 using require_any_t = std::enable_if_t<math::disjunction<Checks...>::value>; 44 45 /** 46 * If all conditions are false, template is enabled. 47 * 48 * Returns a type void if all of the conditions are false. 49 * @ingroup type_traits 50 */ 51 template <class... Checks> 52 using require_all_not_t 53 = std::enable_if_t<!math::disjunction<Checks...>::value>; 54 55 /** 56 * If any condition is false, template is enabled. 57 * 58 * Returns a type void if any of the conditions are false. 59 * @ingroup type_traits 60 */ 61 template <class... Checks> 62 using require_any_not_t 63 = std::enable_if_t<!math::conjunction<Checks...>::value>; 64 65 /** \ingroup macro_helpers 66 * Adds Unary require aliases. 67 * @param check_type The name of the type to check, used to define 68 * `require_<check_type>_t`. 69 * @param checker A struct that returns holds a boolean `value` 70 * @param doxygen_group The doxygen group to add this requires to. 71 */ 72 #define STAN_ADD_REQUIRE_UNARY(check_type, checker, doxygen_group) \ 73 /*! \ingroup doxygen_group */ \ 74 /*! \defgroup check_type##_types check_type */ \ 75 /*! \addtogroup check_type##_types */ \ 76 /*! @{ */ \ 77 /*! \brief Require type satisfies checker */ \ 78 template <typename T> \ 79 using require_##check_type##_t = require_t<checker<std::decay_t<T>>>; \ 80 \ 81 /*! \brief Require type does not satisfy checker */ \ 82 template <typename T> \ 83 using require_not_##check_type##_t \ 84 = require_not_t<checker<std::decay_t<T>>>; \ 85 \ 86 /*! \brief Require all of the types satisfy checker */ \ 87 template <typename... Types> \ 88 using require_all_##check_type##_t \ 89 = require_all_t<checker<std::decay_t<Types>>...>; \ 90 \ 91 /*! \brief Require any of the types satisfy checker */ \ 92 template <typename... Types> \ 93 using require_any_##check_type##_t \ 94 = require_any_t<checker<std::decay_t<Types>>...>; \ 95 \ 96 /*! \brief Require none of the types satisfy checker */ \ 97 template <typename... Types> \ 98 using require_all_not_##check_type##_t \ 99 = require_all_not_t<checker<std::decay_t<Types>>...>; \ 100 \ 101 /*! \brief Require at least one of the types do not satisfy checker */ \ 102 template <typename... Types> \ 103 using require_any_not_##check_type##_t \ 104 = require_any_not_t<checker<std::decay_t<Types>>...>; \ 105 /*! @} */ 106 107 /** \ingroup macro_helpers 108 * Adds unary require aliases that check the `value_type`. 109 * @param check_type The name of the type to check, used to define 110 * `require_<check_type>_t`. 111 * @param checker A struct that returns holds a boolean `value` 112 * @param doxygen_group The doxygen group to add this requires to. 113 */ 114 #define STAN_ADD_REQUIRE_UNARY_INNER(check_type, checker, doxygen_group) \ 115 /*! \ingroup doxygen_group */ \ 116 /*! \addtogroup check_type##_types */ \ 117 /*! @{ */ \ 118 /*! \brief Require value type satisfies checker */ \ 119 template <typename T> \ 120 using require_vt_##check_type \ 121 = require_t<checker<value_type_t<std::decay_t<T>>>>; \ 122 \ 123 /*! \brief Require value type does not satisfy checker */ \ 124 template <typename T> \ 125 using require_not_vt_##check_type \ 126 = require_not_t<checker<value_type_t<std::decay_t<T>>>>; \ 127 \ 128 /*! \brief Require all of the value types satisfy checker */ \ 129 template <typename... Types> \ 130 using require_all_vt_##check_type \ 131 = require_all_t<checker<value_type_t<std::decay_t<Types>>>...>; \ 132 \ 133 /*! \brief Require any of the value types satisfy checker */ \ 134 template <typename... Types> \ 135 using require_any_vt_##check_type \ 136 = require_any_t<checker<value_type_t<std::decay_t<Types>>>...>; \ 137 \ 138 /*! \brief Require none of the value types satisfy checker */ \ 139 template <typename... Types> \ 140 using require_all_not_vt_##check_type \ 141 = require_all_not_t<checker<value_type_t<std::decay_t<Types>>>...>; \ 142 \ 143 /*! \brief Require at least one of the value types do not satisfy checker */ \ 144 template <typename... Types> \ 145 using require_any_not_vt_##check_type \ 146 = require_any_not_t<checker<value_type_t<std::decay_t<Types>>>...>; \ 147 \ 148 /*! \brief Require scalar type satisfies checker */ \ 149 template <typename T> \ 150 using require_st_##check_type \ 151 = require_t<checker<scalar_type_t<std::decay_t<T>>>>; \ 152 \ 153 /*! \brief Require scalar type does not satisfy checker */ \ 154 template <typename T> \ 155 using require_not_st_##check_type \ 156 = require_not_t<checker<scalar_type_t<std::decay_t<T>>>>; \ 157 \ 158 /*! \brief Require all of the scalar types satisfy checker */ \ 159 template <typename... Types> \ 160 using require_all_st_##check_type \ 161 = require_all_t<checker<scalar_type_t<std::decay_t<Types>>>...>; \ 162 \ 163 /*! \brief Require any of the scalar types satisfy checker */ \ 164 template <typename... Types> \ 165 using require_any_st_##check_type \ 166 = require_any_t<checker<scalar_type_t<std::decay_t<Types>>>...>; \ 167 \ 168 /*! \brief Require none of the scalar types satisfy checker */ \ 169 template <typename... Types> \ 170 using require_all_not_st_##check_type \ 171 = require_all_not_t<checker<scalar_type_t<std::decay_t<Types>>>...>; \ 172 \ 173 /*! \brief Any of the scalar types do not satisfy checker */ \ 174 template <typename... Types> \ 175 using require_any_not_st_##check_type \ 176 = require_any_not_t<checker<scalar_type_t<std::decay_t<Types>>>...>; \ 177 /*! @} */ 178 179 /** \ingroup macro_helpers 180 * Adds binary require aliases. 181 * @param check_type The name of the type to check, used to define 182 * `require_<check_type>_t`. 183 * @param checker A struct that returns holds a boolean `value` 184 * @param doxygen_group The doxygen group to add this requires to. 185 */ 186 #define STAN_ADD_REQUIRE_BINARY(check_type, checker, doxygen_group) \ 187 /*! \ingroup doxygen_group */ \ 188 /*! \defgroup check_type##_types check_type */ \ 189 /*! \addtogroup check_type##_types */ \ 190 /*! @{ */ \ 191 /*! \brief Require types `T` and `S` satisfies checker */ \ 192 template <typename T, typename S> \ 193 using require_##check_type##_t \ 194 = require_t<checker<std::decay_t<T>, std::decay_t<S>>>; \ 195 \ 196 /*! \brief Require types `T` and `S` does not satisfy checker */ \ 197 template <typename T, typename S> \ 198 using require_not_##check_type##_t \ 199 = require_not_t<checker<std::decay_t<T>, std::decay_t<S>>>; \ 200 \ 201 /*! \brief Require `T` and all of the `Types` satisfy checker */ \ 202 template <typename T, typename... Types> \ 203 using require_all_##check_type##_t \ 204 = require_all_t<checker<std::decay_t<T>, std::decay_t<Types>>...>; \ 205 \ 206 /*! \brief Require any of the `Types` and `T` satisfy checker */ \ 207 template <typename T, typename... Types> \ 208 using require_any_##check_type##_t \ 209 = require_any_t<checker<std::decay_t<T>, std::decay_t<Types>>...>; \ 210 \ 211 /*! \brief Require none of the `Types` and `T` satisfy checker */ \ 212 template <typename T, typename... Types> \ 213 using require_all_not_##check_type##_t \ 214 = require_all_not_t<checker<std::decay_t<T>, std::decay_t<Types>>...>; \ 215 \ 216 /*! \brief Any one of the `Types` and `T` do not satisfy */ \ 217 template <typename T, typename... Types> \ 218 using require_any_not_##check_type##_t \ 219 = require_any_not_t<checker<std::decay_t<T>, std::decay_t<Types>>...>; \ 220 /*! @} */ 221 222 /** \ingroup macro_helpers 223 * Adds binary require aliases that check the `scalar_type`. 224 * @param check_type The name of the type to check, used to define 225 * `require_<check_type>_t`. 226 * @param checker A struct that returns holds a boolean `value` 227 * @param doxygen_group The doxygen group to add this requires to. 228 */ 229 #define STAN_ADD_REQUIRE_BINARY_INNER(check_type, checker, doxygen_group) \ 230 /*! \ingroup doxygen_group */ \ 231 /*! \addtogroup check_type##_types */ \ 232 /*! @{ */ \ 233 /*! \brief Require that value types of `T` and `S` satisfies checker */ \ 234 template <typename T, typename S> \ 235 using require_st_##check_type \ 236 = require_t<checker<scalar_type_t<std::decay_t<T>>, \ 237 scalar_type_t<std::decay_t<S>>>>; \ 238 \ 239 /*! \brief Require scalar types of `T` and `S` does not satisfy checker */ \ 240 template <typename T, typename S> \ 241 using require_not_st_##check_type \ 242 = require_not_t<checker<scalar_type_t<std::decay_t<T>>, \ 243 scalar_type_t<std::decay_t<S>>>>; \ 244 \ 245 /*! \brief All scalar types of `T` and all of the `Types` satisfy checker */ \ 246 template <typename T, typename... Types> \ 247 using require_all_st_##check_type \ 248 = require_all_t<checker<scalar_type_t<std::decay_t<T>>, \ 249 scalar_type_t<std::decay_t<Types>>>...>; \ 250 \ 251 /*! \brief Any of the scalar types of `Types` and `T` satisfy checker */ \ 252 template <typename T, typename... Types> \ 253 using require_any_st_##check_type \ 254 = require_any_t<checker<scalar_type_t<std::decay_t<T>>, \ 255 scalar_type_t<std::decay_t<Types>>>...>; \ 256 \ 257 /*! \brief None of the scalar types of `Types` and `T` satisfy checker */ \ 258 template <typename T, typename... Types> \ 259 using require_all_not_st_##check_type \ 260 = require_all_not_t<checker<scalar_type_t<std::decay_t<T>>, \ 261 scalar_type_t<std::decay_t<Types>>>...>; \ 262 \ 263 /*! \brief Any of the scalar types `Types` and `T` do not satisfy checker */ \ 264 template <typename T, typename... Types> \ 265 using require_any_not_st_##check_type \ 266 = require_any_not_t<checker<scalar_type_t<std::decay_t<T>>, \ 267 scalar_type_t<std::decay_t<Types>>>...>; \ 268 \ 269 /*! \brief Value types of `T` and `S` satisfies checker */ \ 270 template <typename T, typename S> \ 271 using require_vt_##check_type = require_t< \ 272 checker<value_type_t<std::decay_t<T>>, value_type_t<std::decay_t<S>>>>; \ 273 \ 274 /*! \brief Value types of `T` and `S` does not satisfy checker */ \ 275 template <typename T, typename S> \ 276 using require_not_vt_##check_type = require_not_t< \ 277 checker<value_type_t<std::decay_t<T>>, value_type_t<std::decay_t<S>>>>; \ 278 \ 279 /*! \brief Value types of `T` and all of the `Types` satisfy checker */ \ 280 template <typename T, typename... Types> \ 281 using require_all_vt_##check_type \ 282 = require_all_t<checker<value_type_t<std::decay_t<T>>, \ 283 value_type_t<std::decay_t<Types>>>...>; \ 284 \ 285 /*! \brief Any of the value types of `Types` and `T` satisfy checker */ \ 286 template <typename T, typename... Types> \ 287 using require_any_vt_##check_type \ 288 = require_any_t<checker<value_type_t<std::decay_t<T>>, \ 289 value_type_t<std::decay_t<Types>>>...>; \ 290 \ 291 /*! \brief None of the value types of `Types` and `T` satisfy checker */ \ 292 template <typename T, typename... Types> \ 293 using require_all_not_vt_##check_type \ 294 = require_all_not_t<checker<value_type_t<std::decay_t<T>>, \ 295 value_type_t<std::decay_t<Types>>>...>; \ 296 \ 297 /*! \brief Any of the value types `Types` and `T` do not satisfy checker */ \ 298 template <typename T, typename... Types> \ 299 using require_any_not_vt_##check_type \ 300 = require_any_not_t<checker<value_type_t<std::decay_t<T>>, \ 301 value_type_t<std::decay_t<Types>>>...>; \ 302 /*! @} */ 303 304 /** 305 * Used as the base for checking whether a type is a container with 306 * an underlying scalar type 307 * 308 * @tparam ContainerCheck Templated struct or alias that wraps a static constant 309 * scalar called type. Used to check the container satisfies a particular type 310 * check. 311 * @tparam ValueCheck Templated struct or alias that returns a containers 312 * inner type. 313 * @tparam CheckType Templated struct or alias that wraps a static constant 314 * scalar called type. Used to check the container's underlying type satisfies a 315 * particular type check. 316 * 317 */ 318 template <template <class...> class ContainerCheck, 319 template <class...> class ValueCheck, 320 template <class...> class TypeCheck, class... Check> 321 using container_type_check_base 322 = bool_constant<math::conjunction<ContainerCheck<std::decay_t<Check>>..., 323 TypeCheck<ValueCheck<Check>>...>::value>; 324 325 /** \ingroup macro_helpers 326 * Adds container require aliases that check the containers inner type. 327 * @param check_type The name of the type to check, used to define 328 * `require_<check_type>_t`. 329 * @param checker A struct that returns holds a boolean `value` 330 * @param doxygen_group The doxygen group to add this requires to. 331 */ 332 #define STAN_ADD_REQUIRE_CONTAINER(check_type, checker, doxygen_group) \ 333 /*! \ingroup doxygen_group */ \ 334 /*! \defgroup check_type##_types check_type */ \ 335 /*! \addtogroup check_type##_types */ \ 336 /*! @{ */ \ 337 /*! \brief Require type satisfies checker */ \ 338 /*! and value type satisfies `TypeCheck` */ \ 339 /*! @tparam TypeCheck The type trait to check the value type against*/ \ 340 template <template <class...> class TypeCheck, class... Check> \ 341 using require_##check_type##_vt = require_t< \ 342 container_type_check_base<checker, value_type_t, TypeCheck, Check...>>; \ 343 \ 344 /*! \brief Require type does not satisfy checker or */ \ 345 /*! value type does not satisfy `TypeCheck` */ \ 346 /*! @tparam TypeCheck The type trait to check the value type against*/ \ 347 template <template <class...> class TypeCheck, class... Check> \ 348 using require_not_##check_type##_vt = require_not_t< \ 349 container_type_check_base<checker, value_type_t, TypeCheck, Check...>>; \ 350 \ 351 /*! \brief Require any of the types satisfy checker */ \ 352 /*! and any of the value types satisfy `TypeCheck` */ \ 353 /*! @tparam TypeCheck The type trait to check the value type against*/ \ 354 template <template <class...> class TypeCheck, class... Check> \ 355 using require_any_##check_type##_vt = require_any_t< \ 356 container_type_check_base<checker, value_type_t, TypeCheck, Check>...>; \ 357 \ 358 /*! \brief Require at least one of the types does not satisfy checker */ \ 359 /*! and none of the value types satisfy `TypeCheck` */ \ 360 /*! @tparam TypeCheck The type trait to check the value type against*/ \ 361 template <template <class...> class TypeCheck, class... Check> \ 362 using require_any_not_##check_type##_vt = require_any_not_t< \ 363 container_type_check_base<checker, value_type_t, TypeCheck, Check>...>; \ 364 \ 365 /*! \brief Require all of the types satisfy checker */ \ 366 /*! and all of the value types satisfy `TypeCheck` */ \ 367 /*! @tparam TypeCheck The type trait to check the value type against*/ \ 368 template <template <class...> class TypeCheck, class... Check> \ 369 using require_all_##check_type##_vt = require_all_t< \ 370 container_type_check_base<checker, value_type_t, TypeCheck, Check>...>; \ 371 \ 372 /*! \brief Require none of the types satisfy checker */ \ 373 /*! and none of the value types satisfy `TypeCheck` */ \ 374 /*! @tparam TypeCheck The type trait to check the value type against*/ \ 375 template <template <class...> class TypeCheck, class... Check> \ 376 using require_all_not_##check_type##_vt = require_all_not_t< \ 377 container_type_check_base<checker, value_type_t, TypeCheck, Check>...>; \ 378 \ 379 /*! \brief Require type satisfies checker */ \ 380 /*! and scalar type satisfies `TypeCheck` */ \ 381 /*! @tparam TypeCheck The type trait to check the scalar type against*/ \ 382 template <template <class...> class TypeCheck, class... Check> \ 383 using require_##check_type##_st = require_t< \ 384 container_type_check_base<checker, scalar_type_t, TypeCheck, Check...>>; \ 385 \ 386 /*! \brief Require type does not satisfy checker */ \ 387 /*! or scalar type does not satisfy `TypeCheck` */ \ 388 /*! @tparam TypeCheck The type trait to check the scalar type against*/ \ 389 template <template <class...> class TypeCheck, class... Check> \ 390 using require_not_##check_type##_st = require_not_t< \ 391 container_type_check_base<checker, scalar_type_t, TypeCheck, Check...>>; \ 392 \ 393 /*! \brief Require any of the types satisfy checker */ \ 394 /*! and any scalar type satisfies `TypeCheck` */ \ 395 /*! @tparam TypeCheck The type trait to check the scalar type against*/ \ 396 template <template <class...> class TypeCheck, class... Check> \ 397 using require_any_##check_type##_st = require_any_t< \ 398 container_type_check_base<checker, scalar_type_t, TypeCheck, Check>...>; \ 399 \ 400 /*! \brief Require at least one of the types does not satisfy checker */ \ 401 /*! and any scalar type does not satisfy `TypeCheck` */ \ 402 /*! @tparam TypeCheck The type trait to check the scalar type against*/ \ 403 template <template <class...> class TypeCheck, class... Check> \ 404 using require_any_not_##check_type##_st = require_any_not_t< \ 405 container_type_check_base<checker, scalar_type_t, TypeCheck, Check>...>; \ 406 \ 407 /*! \brief Require all of the types does not satisfy checker */ \ 408 /*! and all scalar types satisfy `TypeCheck` */ \ 409 /*! @tparam TypeCheck The type trait to check the scalar type against*/ \ 410 template <template <class...> class TypeCheck, class... Check> \ 411 using require_all_##check_type##_st = require_all_t< \ 412 container_type_check_base<checker, scalar_type_t, TypeCheck, Check>...>; \ 413 \ 414 /*! \brief Require none of the types satisfy checker */ \ 415 /*! and none of the scalar types satisfy `TypeCheck` */ \ 416 /*! @tparam TypeCheck The type trait to check the scalar type against*/ \ 417 template <template <class...> class TypeCheck, class... Check> \ 418 using require_all_not_##check_type##_st = require_all_not_t< \ 419 container_type_check_base<checker, scalar_type_t, TypeCheck, Check>...>; \ 420 /*! @} */ 421 422 } // namespace stan 423 424 #endif 425