Back to home page

EIC code displayed by LXR

 
 

    


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