Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:45:02

0001 
0002 #ifndef BOOST_CONTRACT_CALL_IF_HPP_
0003 #define BOOST_CONTRACT_CALL_IF_HPP_
0004 
0005 // Copyright (C) 2008-2018 Lorenzo Caminiti
0006 // Distributed under the Boost Software License, Version 1.0 (see accompanying
0007 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
0008 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
0009 
0010 /** @file
0011 Statically disable compilation and execution of functor calls.
0012 
0013 @note   These facilities allow to emulate C++17 <c>if constexpr</c> statements
0014         when used together with functor templates (and C++14 generic lambdas).
0015         Therefore, they are not useful on C++17 compilers where
0016         <c> if constexpr</c> can be directly used instead.
0017 */
0018 
0019 #include <boost/contract/detail/none.hpp>
0020 #include <boost/make_shared.hpp>
0021 #include <boost/shared_ptr.hpp>
0022 #include <boost/utility/enable_if.hpp>
0023 #include <boost/config.hpp>
0024 
0025 /* PRIVATE */
0026 
0027 /** @cond */
0028 
0029 // Boost.ResultOf not always able to deduce lambda result type (on MSVC).
0030 #ifndef BOOST_NO_CXX11_DECLTYPE
0031     #include <boost/utility/declval.hpp>
0032     #define BOOST_CONTRACT_CALL_IF_RESULT_OF_(F) \
0033         decltype(boost::declval<F>()())
0034 #else
0035     #include <boost/utility/result_of.hpp>
0036     #define BOOST_CONTRACT_CALL_IF_RESULT_OF_(F) \
0037         typename boost::result_of<F()>::type
0038 #endif
0039 
0040 /** @endcond */
0041 
0042 /* CODE */
0043 
0044 namespace boost { namespace contract {
0045 
0046 /**
0047 Select compilation and execution of functor template calls using a static
0048 boolean predicate (not needed on C++17 compilers, use <c>if constexpr</c>
0049 instead).
0050 
0051 This class template has no members because it is never used directly, it is only
0052 used via its specializations.
0053 Usually this class template is instantiated only via the return value of
0054 @RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}.
0055 
0056 @see    @RefSect{extras.assertion_requirements__templates_,
0057         Assertion Requirements}
0058 
0059 @tparam Pred    Static boolean predicate that selects which functor template
0060                 call to compile and execute.
0061 @tparam Then Type of the functor template to call if the static predicate
0062         @c Pred is @c true.
0063 @tparam ThenResult Return type of then-branch functor template call (this is
0064         usually automatically deduced by this library so it is never explicitly
0065         specified by the user, and that is why it is often marked as
0066         @c internal_type in this documentation).
0067 */
0068 template<bool Pred, typename Then, typename ThenResult =
0069     #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
0070         boost::contract::detail::none
0071     #else
0072         internal_type
0073     #endif
0074 >
0075 struct call_if_statement {}; // Empty so cannot be used (but copyable).
0076 
0077 /**
0078 Template specialization to dispatch between then-branch functor template calls
0079 that return void and the ones that return non-void (not needed on C++17
0080 compilers, use <c>if constexpr</c> instead).
0081 
0082 
0083 The base class is a call-if statement so the else and else-if statements can be
0084 specified if needed.
0085 Usually this class template is instantiated only via the return value of
0086 @RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}.
0087 
0088 @note   The <c>result_of<Then()>::type</c> expression needs be evaluated only
0089         when the static predicate is already checked to be @c true (because
0090         @c Then() is required to compile only in that case).
0091         Thus, this template specialization introduces an extra level of
0092         indirection necessary for proper lazy evaluation of this result-of
0093         expression.
0094 
0095 @see    @RefSect{extras.assertion_requirements__templates_,
0096         Assertion Requirements}
0097 
0098 @tparam Then Type of functor template to call when the static predicate is
0099         @c true (as it is for this template specialization).
0100 */
0101 template<typename Then>
0102 struct call_if_statement<true, Then,
0103     #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
0104         boost::contract::detail::none
0105     #else
0106         internal_type
0107     #endif
0108 > :
0109     call_if_statement<true, Then,
0110         #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
0111             BOOST_CONTRACT_CALL_IF_RESULT_OF_(Then)
0112         #else
0113             typename result_of<Then()>::type
0114         #endif
0115     >
0116 { // Copyable (as its base).
0117     /**
0118     Construct this object with the then-branch functor template.
0119 
0120     @param f    Then-branch nullary functor template.
0121                 The functor template call @c f() is compiled and called for this
0122                 template specialization (because the if-statement static
0123                 predicate is @c true).
0124                 The return type of @c f() must be the same as (or implicitly
0125                 convertible to) the return type of all other functor template
0126                 calls specified for this call-if object.
0127     */
0128     explicit call_if_statement(Then f) : call_if_statement<true, Then,
0129             BOOST_CONTRACT_CALL_IF_RESULT_OF_(Then)>(f) {}
0130 };
0131 
0132 /**
0133 Template specialization to handle static predicates that are @c true for
0134 then-branch functor template calls that do not return void (not needed on C++17
0135 compilers, use <c>if constexpr</c> instead).
0136 
0137 
0138 Usually this class template is instantiated only via the return value of
0139 @RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}.
0140 
0141 @see    @RefSect{extras.assertion_requirements__templates_,
0142         Assertion Requirements}
0143 
0144 @tparam Then Type of functor template to call when the static predicate is
0145         @c true (as it is for this template specialization).
0146 @tparam ThenResult Non-void return type of the then-branch functor template
0147         call.
0148 */
0149 template<typename Then, typename ThenResult>
0150 struct call_if_statement<true, Then, ThenResult> { // Copyable (as *).
0151     /**
0152     Construct this object with the then-branch functor template.
0153 
0154     @param f    Then-branch nullary functor template.
0155                 The functor template call @c f() is actually compiled and
0156                 executed for this template specialization (because the
0157                 if-statement static predicate is @c true).
0158                 The return type of @c f() must be the same as (or implicitly
0159                 convertible to) the @p ThenResult type.
0160     */
0161     explicit call_if_statement(Then f) :
0162             r_(boost::make_shared<ThenResult>(f())) {}
0163 
0164     /**
0165     This implicit type conversion returns a copy of the value returned by the
0166     call to the then-branch functor template.
0167     */
0168     operator ThenResult() const { return *r_; }
0169 
0170     /**
0171     Specify the else-branch functor template.
0172 
0173     @param f    Else-branch nullary functor template.
0174                 The functor template call @c f() is never compiled or executed
0175                 for this template specialization (because the if-statement
0176                 static predicate is @c true).
0177                 The return type of @c f() must be the same as (or implicitly
0178                 convertible to) the @p ThenResult type.
0179     
0180     @return A copy of the value returned by the call to the then-branch functor
0181             template (because the else-branch functor template call is not
0182             executed).
0183     */
0184     template<typename Else>
0185     ThenResult else_(Else const&
0186         #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
0187             f
0188         #endif
0189     ) const { return *r_; }
0190     
0191     /**
0192     Specify an else-if-branch functor template (using a static boolean
0193     predicate).
0194 
0195     @param f    Else-if-branch nullary functor template.
0196                 The functor template call @c f() is never compiled or executed
0197                 for this template specialization (because the if-statement
0198                 static predicate is @c true).
0199                 The return type of @c f() must be the same as (or implicitly
0200                 convertible to) the @p ThenResult type.
0201     
0202     @tparam ElseIfPred  Static boolean predicate selecting which functor
0203                         template call to compile and execute.
0204     
0205     @return A call-if statement so the else statement and additional else-if
0206             statements can be specified if needed.
0207             Eventually, it will be the return value of the then-branch functor
0208             template call for this template specialization (because the
0209             if-statement static predicate is @c true).
0210     */
0211     template<bool ElseIfPred, typename ElseIfThen>
0212     call_if_statement<true, Then, ThenResult> else_if_c(
0213         ElseIfThen const&
0214         #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN // Avoid unused param warning.
0215             f
0216         #endif
0217     ) const { return *this; }
0218 
0219     /**
0220     Specify an else-if-branch functor template (using a nullary boolean
0221     meta-function).
0222 
0223     @param f    Else-if-branch nullary functor template.
0224                 The functor template call @c f() is never compiled or executed
0225                 for this template specialization (because the if-statement
0226                 static predicate is @c true).
0227                 The return type of @c f() must be the same as (or implicitly
0228                 convertible to) the @p ThenResult type.
0229     
0230     @tparam ElseIfPred  Nullary boolean meta-function selecting which functor
0231                         template call to compile and execute.
0232     
0233     @return A call-if statement so the else statement and additional else-if
0234             statements can be specified if needed.
0235             Eventually, it will be the return value of the then-branch functor
0236             template call for this template specialization (because the
0237             if-statement static predicate is @c true).
0238     */
0239     template<class ElseIfPred, typename ElseIfThen>
0240     call_if_statement<true, Then, ThenResult> else_if(
0241         ElseIfThen const&
0242         #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN // Avoid unused param warning.
0243             f
0244         #endif
0245     ) const { return *this; }
0246     
0247 private:
0248     boost::shared_ptr<ThenResult> r_;
0249 };
0250 
0251 /**
0252 Template specialization to handle static predicates that are @c true for
0253 then-branch functor template calls that return void (not needed on C++17
0254 compilers, use <c>if constexpr</c> instead).
0255 
0256 
0257 Usually this class template is instantiated only via the return value of
0258 @RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}.
0259 
0260 @see    @RefSect{extras.assertion_requirements__templates_,
0261         Assertion Requirements}
0262 
0263 @tparam Then Type of functor template to call when the static predicate if
0264         @c true (as it is for this template specialization).
0265 */
0266 template<typename Then>
0267 struct call_if_statement<true, Then, void> { // Copyable (no data).
0268     /**
0269     Construct this object with the then-branch functor template.
0270 
0271     @param f    Then-branch nullary functor template.
0272                 The functor template call @c f() is actually compiled and
0273                 executed for this template specialization (because the
0274                 if-statement static predicate is @c true).
0275                 The return type of @c f() must be @c void for this template
0276                 specialization (because the then-branch functor template calls
0277                 return void).
0278     */
0279     explicit call_if_statement(Then f) { f(); }
0280     
0281     // Cannot provide `operator ThenResult()` here, because ThenResult is void.
0282 
0283     /**
0284     Specify the else-branch functor template.
0285 
0286     @param f    Else-branch nullary functor template.
0287                 The functor template call @c f() is never compiled or executed
0288                 for this template specialization (because the if-statement
0289                 static predicate is @c true).
0290                 The return type of @c f() must be @c void for this template
0291                 specialization (because the then-branch functor template calls
0292                 return void).
0293     */
0294     template<typename Else>
0295     void else_(Else const&
0296         #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
0297             f
0298         #endif
0299     ) const {}
0300     
0301     /**
0302     Specify an else-if-branch functor template (using a static boolean
0303     predicate).
0304 
0305     @param f    Else-if-branch nullary functor template.
0306                 The functor template call @c f() is never compiled or executed
0307                 for this template specialization (because the if-statement
0308                 static predicate is @c true).
0309                 The return type of @c f() must be @c void for this template
0310                 specialization (because the then-branch functor template calls
0311                 return void).
0312     
0313     @tparam ElseIfPred  Static boolean predicate selecting which functor
0314                         template call to compile and execute.
0315     
0316     @return A call-if statement so the else statement and additional else-if
0317             statements can be specified if needed.
0318             Eventually, it will return void for this template specialization
0319             (because the then-branch functor template calls return void).
0320     */
0321     template<bool ElseIfPred, typename ElseIfThen>
0322     call_if_statement<true, Then, void> else_if_c(
0323         ElseIfThen const&
0324         #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN // Avoid unused param warning.
0325             f
0326         #endif
0327     ) const { return *this; }
0328 
0329     /**
0330     Specify an else-if-branch functor template (using a nullary boolean
0331     meta-function).
0332 
0333     @param f    Else-if-branch nullary functor template.
0334                 The functor template call @c f() is never compiled or executed
0335                 for this template specialization (because the if-statement
0336                 static predicate is @c true).
0337                 The return type of @c f() must be @c void for this template
0338                 specialization (because the then-branch functor template calls
0339                 return void).
0340 
0341     @tparam ElseIfPred  Nullary boolean meta-function selecting which functor
0342                         template call to compile and execute.
0343 
0344     @return A call-if statement so the else statement and additional else-if
0345             statements can be specified if needed.
0346             Eventually, it will return void for this template specialization
0347             (because the then-branch functor template calls return void).
0348     */
0349     template<class ElseIfPred, typename ElseIfThen>
0350     call_if_statement<true, Then, void> else_if(
0351         ElseIfThen const&
0352         #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN // Avoid unused param warning.
0353             f
0354         #endif
0355     ) const { return *this; }
0356 };
0357 
0358 /**
0359 Template specialization to handle static predicates that are @c false (not
0360 needed on C++17 compilers, use <c>if constexpr</c> instead).
0361 
0362 This template specialization handles all else-branch functor template calls
0363 (whether they return void or not).
0364 Usually this class template is instantiated only via the return value of
0365 @RefFunc{boost::contract::call_if} and @RefFunc{boost::contract::call_if_c}.
0366 
0367 @see    @RefSect{extras.assertion_requirements__templates_,
0368         Assertion Requirements}
0369 
0370 @tparam Then Type of functor template to call when the static predicate is
0371         @c true (never the case for this template specialization).
0372 */
0373 template<typename Then> // Copyable (no data).
0374 struct call_if_statement<false, Then,
0375     #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
0376         boost::contract::detail::none
0377     #else
0378         internal_type
0379     #endif
0380 > {
0381     /**
0382     Construct this object with the then-branch functor template.
0383 
0384     @param f    Then-branch nullary functor template.
0385                 The functor template call @c f() is never compiled or executed
0386                 for this template specialization (because the if-statement
0387                 static predicate is @c false).
0388                 The return type of @c f() must be the same as (or implicitly
0389                 convertible to) the return type of all other functor template
0390                 calls specified for this call-if object.
0391     */
0392     explicit call_if_statement(Then const&
0393         #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
0394             f
0395         #endif
0396     ) {}
0397 
0398     // Do not provide `operator result_type()` here, require else_ instead.
0399 
0400     /**
0401     Specify the else-branch functor template.
0402 
0403     @note   The <c>result_of<Else()>::type</c> expression needs be evaluated
0404             only when the static predicate is already checked to be @c false
0405             (because @c Else() is required to compile only in that case).
0406             Thus, this result-of expression is evaluated lazily and only in
0407             instantiations of this template specialization.
0408     
0409     @param f    Else-branch nullary functor template.
0410                 The functor template call @c f() is actually compiled and
0411                 executed for this template specialization (because the
0412                 if-statement static predicate is @c false).
0413                 The return type of @c f() must be the same as (or implicitly
0414                 convertible to) the return type of all other functor template
0415                 calls specified for this call-if object.
0416     
0417     @return A copy of the value returned by the call to the else-branch functor
0418             template @c f().
0419     */
0420     template<typename Else>
0421     #ifndef BOOST_CONTRACT_DETAIL_DOXYGEN
0422         BOOST_CONTRACT_CALL_IF_RESULT_OF_(Else)
0423     #else
0424         typename result_of<Else()>::type
0425     #endif
0426     else_(Else f) const { return f(); }
0427     
0428     /**
0429     Specify an else-if-branch functor template (using a static boolean
0430     predicate).
0431 
0432     @param f    Else-if-branch nullary functor template.
0433                 The functor template call @c f() is actually compiled and
0434                 executed if and only if @c ElseIfPred is @c true (because the
0435                 if-statement static predicate is already @c false for this
0436                 template specialization).
0437                 The return type of @c f() must be the same as (or implicitly
0438                 convertible to) the return type of all other functor template
0439                 calls specified for this call-if object.
0440     
0441     @tparam ElseIfPred  Static boolean predicate selecting which functor
0442                         template call to compile and execute.
0443 
0444     @return A call-if statement so the else statement and additional else-if
0445             statements can be specified if needed.
0446             Eventually, this will be the return value of the one functor
0447             template call being compiled and executed.
0448     */
0449     template<bool ElseIfPred, typename ElseIfThen>
0450     call_if_statement<ElseIfPred, ElseIfThen> else_if_c(ElseIfThen f) const {
0451         return call_if_statement<ElseIfPred, ElseIfThen>(f);
0452     }
0453     
0454     /**
0455     Specify an else-if-branch functor template (using a nullary boolen
0456     meta-function).
0457 
0458     @param f    Else-if-branch nullary functor template.
0459                 The functor template call @c f() is actually compiled and
0460                 executed if and only if @c ElseIfPred::value is @c true (because
0461                 the if-statement static predicate is already @c false for this
0462                 template specialization).
0463                 The return type of @c f() must be the same as (or implicitly
0464                 convertible to) the return type of all other functor template
0465                 calls specified for this call-if object.
0466 
0467     @tparam ElseIfPred  Nullary boolean meta-function selecting which functor
0468                         template call to compile and execute.
0469 
0470     @return A call-if statement so the else statement and additional else-if
0471             statements can be specified if needed.
0472             Eventually, this will be the return value of the one functor
0473             template call being compiled and executed.
0474     */
0475     template<class ElseIfPred, typename ElseIfThen>
0476     call_if_statement<ElseIfPred::value, ElseIfThen> else_if(ElseIfThen f)
0477             const {
0478         return call_if_statement<ElseIfPred::value, ElseIfThen>(f);
0479     }
0480 };
0481 
0482 /**
0483 Select compilation and execution of functor template calls using a static
0484 boolean predicate (not needed on C++17 compilers, use <c>if constexpr</c>
0485 instead).
0486 
0487 Create a call-if object with the specified then-branch functor template:
0488 
0489 @code
0490 boost::contract::call_if_c<Pred1>(
0491     then_functor_template1
0492 ).template else_if_c<Pred2>(            // Optional.
0493     then_functor_template2
0494 )                                       // Optionally, other `else_if_c` or
0495 ...                                     // `else_if`.
0496 .else_(                                 // Optional for `void` functors,
0497     else_functor_template               // but required for non `void`.
0498 )
0499 @endcode
0500 
0501 Optional functor templates for else-if-branches and the else-branch can be
0502 specified as needed (the else-branch function template is required if @c f
0503 returns non-void).
0504 
0505 @see    @RefSect{extras.assertion_requirements__templates_,
0506         Assertion Requirements}
0507 
0508 @param f    Then-branch nullary functor template.
0509             The functor template call @c f() is compiled and executed if and
0510             only if @c Pred is @c true.
0511             The return type of other functor template calls specified for this
0512             call-if statement (else-branch, else-if-branches, etc.) must be the
0513             same as (or implicitly convertible to) the return type of
0514             then-branch functor call @c f().
0515 
0516 @tparam Pred    Static boolean predicate selecting which functor template call
0517                 to compile and execute.
0518 
0519 @return A call-if statement so else and else-if statements can be specified if
0520         needed.
0521         Eventually, this will be the return value of the one functor template
0522         call being compiled and executed (which could also be @c void).
0523 */
0524 template<bool Pred, typename Then>
0525 call_if_statement<Pred, Then> call_if_c(Then f) {
0526     return call_if_statement<Pred, Then>(f);
0527 }
0528 
0529 /**
0530 Select compilation and execution of functor template calls using a nullary
0531 boolean meta-function (not needed on C++17 compilers, use <c>if constexpr</c>
0532 instead).
0533 
0534 This is equivalent to <c>boost::contract::call_if_c<Pred::value>(f)</c>.
0535 Create a call-if object with the specified then-branch functor template:
0536 
0537 @code
0538 boost::contract::call_if<Pred1>(
0539     then_functor_template1
0540 ).template else_if<Pred2>(              // Optional.
0541     then_functor_template2
0542 )                                       // Optionally, other `else_if` or
0543 ...                                     // `else_if_c`.
0544 .else_(                                 // Optional for `void` functors,
0545     else_functor_template               // but required for non `void`.
0546 )
0547 @endcode
0548 
0549 Optional functor templates for else-if-branches and the else-branch can be
0550 specified as needed (the else-branch functor template is required if @c f
0551 returns non-void).
0552 
0553 @see    @RefSect{extras.assertion_requirements__templates_,
0554         Assertion Requirements}
0555 
0556 @param f    Then-branch nullary functor template.
0557             The functor template call @c f() is compiled and executed if and
0558             only if @c Pred::value is @c true.
0559             The return type of other functor template calls specified for this
0560             call-if statement (else-branch, else-if-branches, etc.) must be the
0561             same as (or implicitly convertible to) the return type of
0562             then-branch functor template call @c f().
0563 
0564 @tparam Pred    Nullary boolean meta-function selecting which functor template
0565                 call to compile and execute.
0566 
0567 @return A call-if statement so else and else-if statements can be specified if
0568         needed.
0569         Eventually, this will be the return value of the one functor template
0570         call being compiled and executed (which could also be @c void).
0571 */
0572 template<class Pred, typename Then>
0573 call_if_statement<Pred::value, Then> call_if(Then f) {
0574     return call_if_statement<Pred::value, Then>(f);
0575 }
0576 
0577 /**
0578 Select compilation and execution of a boolean functor template condition using a
0579 static boolean predicate (not needed on C++17 compilers, use
0580 <c>if constexpr</c> instead).
0581 
0582 Compile and execute the nullary boolean functor template call @c f() if and only
0583 if the specified static boolean predicate @p Pred is @c true, otherwise
0584 trivially return @p else_ (@c true by default) at run-time.
0585 
0586 A call to <c>boost::contract::condition_if_c<Pred>(f, else_)</c> is logically
0587 equivalent to <c>boost::contract::call_if_c<Pred>(f, [] { return else_; })</c>
0588 (but its internal implementation is optimized and it does not actually use
0589 @c call_if_c).
0590 
0591 @see    @RefSect{extras.assertion_requirements__templates_,
0592         Assertion Requirements}
0593 
0594 @param f    Nullary boolean functor template.
0595             The functor template call @c f() is compiled and executed if and
0596             only if @c Pred is @c true.
0597 
0598 @tparam Pred    Static boolean predicate selecting when the functor template
0599                 call @c f() should be compiled and executed.
0600 @param else_    Boolean value to return when @c Pred is @c false (instead of
0601                 compiling and executing the functor template call @c f()).
0602 
0603 @return Boolean value returned by @c f() if the static predicate @c Pred is
0604         @c true. Otherwise, trivially return @p else_.
0605 */
0606 #ifdef BOOST_CONTRACT_DETAIL_DOXYGEN
0607     template<bool Pred, typename Then>
0608     bool condition_if_c(Then f, bool else_ = true);
0609 #else
0610     // NOTE: condition_if is a very simple special case of call_if so it can be
0611     // trivially implemented using enable_if instead of call_if as done below.
0612 
0613     template<bool Pred, typename Then>
0614     typename boost::enable_if_c<Pred, bool>::type
0615     condition_if_c(Then f, bool /* else_ */ = true) { return f(); }
0616 
0617     template<bool Pred, typename Then>
0618     typename boost::disable_if_c<Pred, bool>::type
0619     condition_if_c(Then /* f */, bool else_ = true) { return else_; }
0620 #endif
0621 
0622 /**
0623 Select compilation and execution of a boolean functor template condition using a
0624 nullary boolean meta-function (not needed on C++17 compilers, use
0625 <c>if constexpr</c> instead).
0626 
0627 This is equivalent to
0628 <c>boost::contract::condition_if_c<Pred::value>(f, else_)</c>.
0629 Compile and execute the nullary boolean functor template call @c f() if and only
0630 if the specified nullary boolean meta-function @p Pred::value is @c true,
0631 otherwise trivially return @p else_ (@c true by default) at run-time.
0632 
0633 @see    @RefSect{extras.assertion_requirements__templates_,
0634         Assertion Requirements}
0635 
0636 @param f    Nullary boolean functor template.
0637             The functor template call @c f() is compiled and executed if and
0638             only if @c Pred::value is @c true.
0639 @param else_    Boolean value to return when @c Pred::value is @c false (instead
0640                 of compiling and executing the functor template call @c f()).
0641 
0642 @tparam Pred    Nullary boolean meta-function selecting when the functor
0643                 template call @c f() should be compiled and executed.
0644 
0645 @return Boolean value returned by @c f() if the static predicate @c Pred::value
0646         is @c true. Otherwise, trivially return @p else_.
0647 */
0648 template<class Pred, typename Then>
0649 bool condition_if(Then f, bool else_ = true) {
0650     return condition_if_c<Pred::value>(f, else_);
0651 }
0652 
0653 } } // namespace
0654 
0655 #endif // #include guard
0656