|
||||
File indexing completed on 2025-01-18 09:38:01
0001 /*! 0002 @file 0003 Defines macros to perform different kinds of assertions. 0004 0005 Copyright Louis Dionne 2013-2022 0006 Distributed under the Boost Software License, Version 1.0. 0007 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) 0008 */ 0009 0010 #ifndef BOOST_HANA_ASSERT_HPP 0011 #define BOOST_HANA_ASSERT_HPP 0012 0013 #include <boost/hana/concept/constant.hpp> 0014 #include <boost/hana/config.hpp> 0015 #include <boost/hana/detail/preprocessor.hpp> 0016 #include <boost/hana/if.hpp> 0017 #include <boost/hana/value.hpp> 0018 0019 #include <cstdio> 0020 #include <cstdlib> 0021 0022 0023 #if defined(BOOST_HANA_DOXYGEN_INVOKED) 0024 //! @ingroup group-assertions 0025 //! Expands to a runtime assertion. 0026 //! 0027 //! Given a condition known at runtime, this macro expands to a runtime 0028 //! assertion similar to the `assert` macro. The provided condition must 0029 //! be explicitly convertible to a `bool`, and it must not be a model of 0030 //! the `Constant` concept. If the condition is a `Constant`, a static 0031 //! assertion will be triggered, asking you to use the 0032 //! `BOOST_HANA_CONSTANT_ASSERT` macro instead. 0033 //! 0034 //! @note 0035 //! This macro may only be used at function scope. 0036 # define BOOST_HANA_RUNTIME_ASSERT(condition) unspecified 0037 0038 //! @ingroup group-assertions 0039 //! Equivalent to `BOOST_HANA_RUNTIME_ASSERT`, but allows providing a 0040 //! custom failure message. 0041 //! 0042 //! @warning 0043 //! Conditions that contain multiple comma-separated elements should be 0044 //! parenthesized. 0045 # define BOOST_HANA_RUNTIME_ASSERT_MSG(condition, message) unspecified 0046 0047 //! @ingroup group-assertions 0048 //! Compile-time assertion for `Constant`s. 0049 //! 0050 //! Given a condition known at compile-time in the form of a `Constant`, 0051 //! this macro expands to a compile-time assertion similar to a `static_assert`. 0052 //! The provided condition must be a model of the `Constant` concept, in 0053 //! which case its value is retrieved using `hana::value` and then converted 0054 //! to a `bool`. If the condition is not a `Constant`, a static assertion 0055 //! will be triggered, asking you to use the `BOOST_HANA_RUNTIME_ASSERT` 0056 //! macro instead. 0057 //! 0058 //! This macro may be used at global/namespace scope and function scope 0059 //! only; it may not be used at class scope. Note that the condition may 0060 //! never be evaluated at runtime. Hence, any side effect may not take 0061 //! place (but you shouldn't rely on side effects inside assertions anyway). 0062 # define BOOST_HANA_CONSTANT_ASSERT(condition) unspecified 0063 0064 //! @ingroup group-assertions 0065 //! Equivalent to `BOOST_HANA_CONSTANT_ASSERT`, but allows providing a 0066 //! custom failure message. 0067 //! 0068 //! @warning 0069 //! Conditions that contain multiple comma-separated elements should be 0070 //! parenthesized. 0071 # define BOOST_HANA_CONSTANT_ASSERT_MSG(condition, message) unspecified 0072 0073 //! @ingroup group-assertions 0074 //! Expands to the strongest form of assertion possible for the given 0075 //! condition. 0076 //! 0077 //! Given a condition, `BOOST_HANA_ASSERT` expands either to a compile-time 0078 //! or to a runtime assertion, depending on whether the value of the 0079 //! condition is known at compile-time or at runtime. Compile-time 0080 //! assertions are always preferred over runtime assertions. If the 0081 //! condition is a model of the `Constant` concept, its value (retrievable 0082 //! with `hana::value`) is assumed to be explicitly convertible to `bool`, 0083 //! and a compile-time assertion is performed on it. Otherwise, the 0084 //! condition itself is assumed to be explicitly convertible to `bool`, 0085 //! and a runtime assertion is performed on it. 0086 //! 0087 //! If the assertion can be carried out at compile-time, the condition 0088 //! is not guaranteed to be evaluated at runtime at all (but it may). 0089 //! Hence, in general, you shouldn't rely on side effects that take place 0090 //! inside an assertion. 0091 //! 0092 //! @note 0093 //! This macro may only be used at function scope. 0094 # define BOOST_HANA_ASSERT(condition) unspecified 0095 0096 //! @ingroup group-assertions 0097 //! Equivalent to `BOOST_HANA_ASSERT`, but allows providing a custom 0098 //! failure message. 0099 //! 0100 //! @warning 0101 //! Conditions that contain multiple comma-separated elements should be 0102 //! parenthesized. 0103 # define BOOST_HANA_ASSERT_MSG(condition, message) unspecified 0104 0105 //! @ingroup group-assertions 0106 //! Expands to a static assertion or a runtime assertion, depending on 0107 //! whether `constexpr` lambdas are supported. 0108 //! 0109 //! This macro is used to assert on a condition that would be a constant 0110 //! expression if constexpr lambdas were supported. Right now, constexpr 0111 //! lambdas are not supported, and this is always a runtime assertion. 0112 //! Specifically, this is equivalent to `BOOST_HANA_RUNTIME_ASSERT`. 0113 # define BOOST_HANA_CONSTEXPR_ASSERT(condition) unspecified 0114 0115 //! @ingroup group-assertions 0116 //! Equivalent to `BOOST_HANA_CONSTEXPR_ASSERT`, but allows providing a 0117 //! custom failure message. 0118 # define BOOST_HANA_CONSTEXPR_ASSERT_MSG(condition, message) unspecified 0119 0120 #elif defined(BOOST_HANA_CONFIG_DISABLE_ASSERTIONS) 0121 0122 # define BOOST_HANA_CONSTANT_ASSERT(...) /* nothing */ 0123 # define BOOST_HANA_CONSTANT_ASSERT_MSG(condition, message) /* nothing */ 0124 0125 # define BOOST_HANA_RUNTIME_ASSERT(...) /* nothing */ 0126 # define BOOST_HANA_RUNTIME_ASSERT_MSG(condition, message) /* nothing */ 0127 0128 # define BOOST_HANA_ASSERT(...) /* nothing */ 0129 # define BOOST_HANA_ASSERT_MSG(condition, message) /* nothing */ 0130 0131 # define BOOST_HANA_CONSTEXPR_ASSERT(...) /* nothing */ 0132 # define BOOST_HANA_CONSTEXPR_ASSERT_MSG(condition, message) /* nothing */ 0133 0134 #else 0135 0136 ////////////////////////////////////////////////////////////////////////////// 0137 // BOOST_HANA_RUNTIME_ASSERT and BOOST_HANA_RUNTIME_ASSERT_MSG 0138 ////////////////////////////////////////////////////////////////////////////// 0139 # define BOOST_HANA_RUNTIME_ASSERT_MSG(condition, message) \ 0140 BOOST_HANA_RUNTIME_CHECK_MSG(condition, message) \ 0141 /**/ 0142 0143 # define BOOST_HANA_RUNTIME_ASSERT(...) \ 0144 BOOST_HANA_RUNTIME_CHECK(__VA_ARGS__) \ 0145 /**/ 0146 0147 ////////////////////////////////////////////////////////////////////////////// 0148 // BOOST_HANA_CONSTANT_ASSERT and BOOST_HANA_CONSTANT_ASSERT_MSG 0149 ////////////////////////////////////////////////////////////////////////////// 0150 # define BOOST_HANA_CONSTANT_ASSERT_MSG(condition, message) \ 0151 BOOST_HANA_CONSTANT_CHECK_MSG(condition, message) \ 0152 /**/ 0153 0154 # define BOOST_HANA_CONSTANT_ASSERT(...) \ 0155 BOOST_HANA_CONSTANT_CHECK(__VA_ARGS__) \ 0156 /**/ 0157 0158 ////////////////////////////////////////////////////////////////////////////// 0159 // BOOST_HANA_ASSERT and BOOST_HANA_ASSERT_MSG 0160 ////////////////////////////////////////////////////////////////////////////// 0161 # define BOOST_HANA_ASSERT_MSG(condition, message) \ 0162 BOOST_HANA_CHECK_MSG(condition, message) \ 0163 /**/ 0164 0165 # define BOOST_HANA_ASSERT(...) \ 0166 BOOST_HANA_CHECK(__VA_ARGS__) \ 0167 /**/ 0168 0169 ////////////////////////////////////////////////////////////////////////////// 0170 // BOOST_HANA_CONSTEXPR_ASSERT and BOOST_HANA_CONSTEXPR_ASSERT_MSG 0171 ////////////////////////////////////////////////////////////////////////////// 0172 # define BOOST_HANA_CONSTEXPR_ASSERT_MSG(condition, message) \ 0173 BOOST_HANA_CONSTEXPR_CHECK_MSG(condition, message) \ 0174 /**/ 0175 0176 # define BOOST_HANA_CONSTEXPR_ASSERT(...) \ 0177 BOOST_HANA_CONSTEXPR_CHECK(__VA_ARGS__) \ 0178 /**/ 0179 0180 #endif 0181 0182 ////////////////////////////////////////////////////////////////////////////// 0183 // BOOST_HANA_RUNTIME_CHECK and BOOST_HANA_RUNTIME_CHECK_MSG 0184 ////////////////////////////////////////////////////////////////////////////// 0185 0186 //! @ingroup group-assertions 0187 //! Equivalent to `BOOST_HANA_RUNTIME_ASSERT_MSG`, but not influenced by the 0188 //! `BOOST_HANA_CONFIG_DISABLE_ASSERTIONS` config macro. For internal use only. 0189 # define BOOST_HANA_RUNTIME_CHECK_MSG(condition, message) \ 0190 do { \ 0191 auto __hana_tmp = condition; \ 0192 static_assert(!::boost::hana::Constant<decltype(__hana_tmp)>::value,\ 0193 "the expression (" # condition ") yields a Constant; " \ 0194 "use BOOST_HANA_CONSTANT_ASSERT instead"); \ 0195 \ 0196 if (!static_cast<bool>(__hana_tmp)) { \ 0197 ::std::fprintf(stderr, "Assertion failed: " \ 0198 "(%s), function %s, file %s, line %i.\n", \ 0199 message, __func__, __FILE__, __LINE__); \ 0200 ::std::abort(); \ 0201 } \ 0202 } while (false); \ 0203 static_assert(true, "force trailing semicolon") \ 0204 /**/ 0205 0206 //! @ingroup group-assertions 0207 //! Equivalent to `BOOST_HANA_RUNTIME_ASSERT`, but not influenced by the 0208 //! `BOOST_HANA_CONFIG_DISABLE_ASSERTIONS` config macro. For internal use only. 0209 # define BOOST_HANA_RUNTIME_CHECK(...) \ 0210 BOOST_HANA_RUNTIME_CHECK_MSG( \ 0211 (__VA_ARGS__), \ 0212 BOOST_HANA_PP_STRINGIZE(__VA_ARGS__) \ 0213 ) \ 0214 /**/ 0215 0216 ////////////////////////////////////////////////////////////////////////////// 0217 // BOOST_HANA_CONSTANT_CHECK and BOOST_HANA_CONSTANT_CHECK_MSG 0218 ////////////////////////////////////////////////////////////////////////////// 0219 0220 //! @ingroup group-assertions 0221 //! Equivalent to `BOOST_HANA_CONSTANT_ASSERT_MSG`, but not influenced by the 0222 //! `BOOST_HANA_CONFIG_DISABLE_ASSERTIONS` config macro. For internal use only. 0223 # define BOOST_HANA_CONSTANT_CHECK_MSG(condition, message) \ 0224 auto BOOST_HANA_PP_CONCAT(__hana_tmp_, __LINE__) = condition; \ 0225 static_assert(::boost::hana::Constant< \ 0226 decltype(BOOST_HANA_PP_CONCAT(__hana_tmp_, __LINE__)) \ 0227 >::value, \ 0228 "the expression " # condition " does not yield a Constant; " \ 0229 "use BOOST_HANA_RUNTIME_ASSERT instead"); \ 0230 static_assert(::boost::hana::value< \ 0231 decltype(BOOST_HANA_PP_CONCAT(__hana_tmp_, __LINE__)) \ 0232 >(), message); \ 0233 static_assert(true, "force trailing semicolon") \ 0234 /**/ 0235 0236 //! @ingroup group-assertions 0237 //! Equivalent to `BOOST_HANA_CONSTANT_ASSERT`, but not influenced by the 0238 //! `BOOST_HANA_CONFIG_DISABLE_ASSERTIONS` config macro. For internal use only. 0239 # define BOOST_HANA_CONSTANT_CHECK(...) \ 0240 BOOST_HANA_CONSTANT_CHECK_MSG( \ 0241 (__VA_ARGS__), \ 0242 BOOST_HANA_PP_STRINGIZE(__VA_ARGS__) \ 0243 ) \ 0244 /**/ 0245 0246 ////////////////////////////////////////////////////////////////////////////// 0247 // BOOST_HANA_CHECK and BOOST_HANA_CHECK_MSG 0248 ////////////////////////////////////////////////////////////////////////////// 0249 0250 //! @ingroup group-assertions 0251 //! Equivalent to `BOOST_HANA_ASSERT_MSG`, but not influenced by the 0252 //! `BOOST_HANA_CONFIG_DISABLE_ASSERTIONS` config macro. For internal use only. 0253 # define BOOST_HANA_CHECK_MSG(condition, message) \ 0254 do { \ 0255 auto __hana_tmp = condition; \ 0256 ::boost::hana::if_(::boost::hana::bool_c< \ 0257 ::boost::hana::Constant<decltype(__hana_tmp)>::value>, \ 0258 [](auto expr) { \ 0259 static_assert(::boost::hana::value<decltype(expr)>(), \ 0260 message); \ 0261 }, \ 0262 [](auto expr) { \ 0263 if (!static_cast<bool>(expr)) { \ 0264 ::std::fprintf(stderr, "Assertion failed: " \ 0265 "(%s), function %s, file %s, line %i.\n", \ 0266 message, __func__, __FILE__, __LINE__); \ 0267 ::std::abort(); \ 0268 } \ 0269 } \ 0270 )(__hana_tmp); \ 0271 } while (false); \ 0272 static_assert(true, "force trailing semicolon") \ 0273 /**/ 0274 0275 //! @ingroup group-assertions 0276 //! Equivalent to `BOOST_HANA__ASSERT`, but not influenced by the 0277 //! `BOOST_HANA_CONFIG_DISABLE_ASSERTIONS` config macro. For internal use only. 0278 # define BOOST_HANA_CHECK(...) \ 0279 BOOST_HANA_CHECK_MSG( \ 0280 (__VA_ARGS__), \ 0281 BOOST_HANA_PP_STRINGIZE(__VA_ARGS__) \ 0282 ) \ 0283 /**/ 0284 0285 ////////////////////////////////////////////////////////////////////////////// 0286 // BOOST_HANA_CONSTEXPR_CHECK and BOOST_HANA_CONSTEXPR_CHECK_MSG 0287 ////////////////////////////////////////////////////////////////////////////// 0288 0289 #if defined(BOOST_HANA_DOXYGEN_INVOKED) 0290 //! @ingroup group-assertions 0291 //! Equivalent to `BOOST_HANA_CONSTEXPR_ASSERT_MSG`, but not influenced by 0292 //! the `BOOST_HANA_CONFIG_DISABLE_ASSERTIONS` config macro. 0293 //! For internal use only. 0294 # define BOOST_HANA_CONSTEXPR_CHECK_MSG(condition, message) implementation-defined 0295 0296 //! @ingroup group-assertions 0297 //! Equivalent to `BOOST_HANA_CONSTEXPR_ASSERT`, but not influenced by the 0298 //! `BOOST_HANA_CONFIG_DISABLE_ASSERTIONS` config macro. 0299 //! For internal use only. 0300 # define BOOST_HANA_CONSTEXPR_CHECK(...) implementation-defined 0301 0302 #elif defined(BOOST_HANA_CONFIG_HAS_CONSTEXPR_LAMBDA) 0303 0304 # define BOOST_HANA_CONSTEXPR_CHECK_MSG(condition, message) \ 0305 static_assert(condition, message) \ 0306 /**/ 0307 0308 # define BOOST_HANA_CONSTEXPR_CHECK(...) \ 0309 static_assert((__VA_ARGS__), BOOST_HANA_PP_STRINGIZE(__VA_ARGS__)) \ 0310 /**/ 0311 0312 #else 0313 0314 # define BOOST_HANA_CONSTEXPR_CHECK_MSG(condition, message) \ 0315 BOOST_HANA_RUNTIME_CHECK_MSG(condition, message) \ 0316 /**/ 0317 0318 # define BOOST_HANA_CONSTEXPR_CHECK(...) \ 0319 BOOST_HANA_CONSTEXPR_CHECK_MSG( \ 0320 (__VA_ARGS__), \ 0321 BOOST_HANA_PP_STRINGIZE(__VA_ARGS__) \ 0322 ) \ 0323 /**/ 0324 0325 #endif 0326 0327 #endif // !BOOST_HANA_ASSERT_HPP
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |