Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:16

0001 /*=============================================================================
0002     Copyright (c) 2014 Paul Fultz II
0003     returns.h
0004     Distributed under the Boost Software License, Version 1.0. (See accompanying
0005     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 ==============================================================================*/
0007 
0008 #ifndef BOOST_HOF_GUARD_RETURNS_H
0009 #define BOOST_HOF_GUARD_RETURNS_H
0010 
0011 /// BOOST_HOF_RETURNS
0012 /// ===========
0013 /// 
0014 /// Description
0015 /// -----------
0016 /// 
0017 /// The `BOOST_HOF_RETURNS` macro defines the function as the expression
0018 /// equivalence. It does this by deducing `noexcept` and the return type by
0019 /// using a trailing `decltype`. Instead of repeating the expression for the
0020 /// return type, `noexcept` clause and the function body, this macro will
0021 /// reduce the code duplication from that.
0022 /// 
0023 /// Note: The expression used to deduce the return the type will also
0024 /// constrain the template function and deduce `noexcept` as well, which is
0025 /// different behaviour than using C++14's return type deduction.
0026 /// 
0027 /// Synopsis
0028 /// --------
0029 /// 
0030 ///     #define BOOST_HOF_RETURNS(...) 
0031 /// 
0032 /// 
0033 /// Example
0034 /// -------
0035 /// 
0036 ///     #include <boost/hof.hpp>
0037 ///     #include <cassert>
0038 /// 
0039 ///     template<class T, class U>
0040 ///     auto sum(T x, U y) BOOST_HOF_RETURNS(x+y);
0041 /// 
0042 ///     int main() {
0043 ///         assert(3 == sum(1, 2));
0044 ///     }
0045 /// 
0046 /// 
0047 /// Incomplete this
0048 /// ---------------
0049 /// 
0050 /// Description
0051 /// -----------
0052 /// 
0053 /// On some non-conformant compilers, such as gcc, the `this` variable cannot
0054 /// be used inside the `BOOST_HOF_RETURNS` macro because it is considered an
0055 /// incomplete type. So the following macros are provided to help workaround
0056 /// the issue.
0057 /// 
0058 /// 
0059 /// Synopsis
0060 /// --------
0061 /// 
0062 ///     // Declares the type of the `this` variable
0063 ///     #define BOOST_HOF_RETURNS_CLASS(...) 
0064 ///     // Used to refer to the `this` variable in the BOOST_HOF_RETURNS macro
0065 ///     #define BOOST_HOF_THIS
0066 ///     // Used to refer to the const `this` variable in the BOOST_HOF_RETURNS macro
0067 ///     #define BOOST_HOF_CONST_THIS
0068 /// 
0069 /// 
0070 /// Example
0071 /// -------
0072 /// 
0073 ///     #include <boost/hof.hpp>
0074 ///     #include <cassert>
0075 /// 
0076 ///     struct add_1
0077 ///     {
0078 ///         int a;
0079 ///         add_1() : a(1) {}
0080 ///         
0081 ///         BOOST_HOF_RETURNS_CLASS(add_1);
0082 ///         
0083 ///         template<class T>
0084 ///         auto operator()(T x) const 
0085 ///         BOOST_HOF_RETURNS(x+BOOST_HOF_CONST_THIS->a);
0086 ///     };
0087 /// 
0088 ///     int main() {
0089 ///         assert(3 == add_1()(2));
0090 ///     }
0091 /// 
0092 /// 
0093 /// Mangling overloads
0094 /// ------------------
0095 /// 
0096 /// Description
0097 /// -----------
0098 /// 
0099 /// On older compilers some operations done in the expressions cannot be
0100 /// properly mangled. These macros help provide workarounds for these
0101 /// operations on older compilers.
0102 /// 
0103 /// 
0104 /// Synopsis
0105 /// --------
0106 /// 
0107 ///     // Explicitly defines the type for name mangling
0108 ///     #define BOOST_HOF_MANGLE_CAST(...) 
0109 ///     // C cast for name mangling
0110 ///     #define BOOST_HOF_RETURNS_C_CAST(...) 
0111 ///     // Reinterpret cast for name mangling
0112 ///     #define BOOST_HOF_RETURNS_REINTERPRET_CAST(...) 
0113 ///     // Static cast for name mangling
0114 ///     #define BOOST_HOF_RETURNS_STATIC_CAST(...) 
0115 ///     // Construction for name mangling
0116 ///     #define BOOST_HOF_RETURNS_CONSTRUCT(...) 
0117 /// 
0118 
0119 
0120 #include <boost/hof/config.hpp>
0121 #include <utility>
0122 #include <boost/hof/detail/forward.hpp>
0123 #include <boost/hof/detail/noexcept.hpp>
0124 
0125 #define BOOST_HOF_EAT(...)
0126 #define BOOST_HOF_REM(...) __VA_ARGS__
0127 
0128 #if BOOST_HOF_HAS_COMPLETE_DECLTYPE && BOOST_HOF_HAS_MANGLE_OVERLOAD
0129 #ifdef _MSC_VER
0130 // Since decltype can't be used in noexcept on MSVC, we can't check for noexcept
0131 // move constructors.
0132 #define BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(...) BOOST_HOF_NOEXCEPT(noexcept(__VA_ARGS__))
0133 #else
0134 #define BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(...) BOOST_HOF_NOEXCEPT(noexcept(static_cast<decltype(__VA_ARGS__)>(__VA_ARGS__)))
0135 #endif
0136 #define BOOST_HOF_RETURNS(...) \
0137 BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(__VA_ARGS__) \
0138 -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
0139 #define BOOST_HOF_THIS this
0140 #define BOOST_HOF_CONST_THIS this
0141 #define BOOST_HOF_RETURNS_CLASS(...) \
0142 void fit_returns_class_check() \
0143 { \
0144     static_assert(std::is_same<__VA_ARGS__*, decltype(this)>::value, \
0145         "Returns class " #__VA_ARGS__ " type doesn't match"); \
0146 }
0147 
0148 #define BOOST_HOF_MANGLE_CAST(...) BOOST_HOF_REM
0149 
0150 #define BOOST_HOF_RETURNS_C_CAST(...) (__VA_ARGS__) BOOST_HOF_REM
0151 #define BOOST_HOF_RETURNS_REINTERPRET_CAST(...) reinterpret_cast<__VA_ARGS__>
0152 #define BOOST_HOF_RETURNS_STATIC_CAST(...) static_cast<__VA_ARGS__>
0153 #define BOOST_HOF_RETURNS_CONSTRUCT(...) __VA_ARGS__
0154 #else
0155 #include <boost/hof/detail/pp.hpp>
0156 
0157 #define BOOST_HOF_RETURNS_RETURN(...) return BOOST_HOF_RETURNS_RETURN_X(BOOST_HOF_PP_WALL(__VA_ARGS__))
0158 #define BOOST_HOF_RETURNS_RETURN_X(...) __VA_ARGS__
0159 
0160 #ifdef _MSC_VER
0161 // Since decltype can't be used in noexcept on MSVC, we can't check for noexcept
0162 // move constructors.
0163 #define BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(...) BOOST_HOF_NOEXCEPT(noexcept(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(__VA_ARGS__)))
0164 #else
0165 #define BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(...) BOOST_HOF_NOEXCEPT(noexcept(static_cast<decltype(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(__VA_ARGS__))>(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(__VA_ARGS__))))
0166 #endif
0167 
0168 #define BOOST_HOF_RETURNS_DECLTYPE(...) \
0169 -> decltype(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(__VA_ARGS__))
0170 
0171 #define BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(...) BOOST_HOF_RETURNS_DECLTYPE_CONTEXT_X(BOOST_HOF_PP_WALL(__VA_ARGS__))
0172 #define BOOST_HOF_RETURNS_DECLTYPE_CONTEXT_X(...) __VA_ARGS__
0173 
0174 #define BOOST_HOF_RETURNS_THAT(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\
0175     (boost::hof::detail::check_this<__VA_ARGS__, decltype(this)>(), this), \
0176     std::declval<__VA_ARGS__>() \
0177 )
0178 
0179 #define BOOST_HOF_THIS BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_THAT)(fit_this_type)
0180 #define BOOST_HOF_CONST_THIS BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_THAT)(fit_const_this_type)
0181 
0182 #define BOOST_HOF_RETURNS_CLASS(...) typedef __VA_ARGS__* fit_this_type; typedef const __VA_ARGS__* fit_const_this_type
0183 
0184 #define BOOST_HOF_RETURNS(...) \
0185 BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(__VA_ARGS__) \
0186 BOOST_HOF_RETURNS_DECLTYPE(__VA_ARGS__) \
0187 { BOOST_HOF_RETURNS_RETURN(__VA_ARGS__); }
0188 
0189 
0190 namespace boost { namespace hof { namespace detail {
0191 template<class Assumed, class T>
0192 struct check_this
0193 {
0194     static_assert(std::is_same<T, Assumed>::value, "Incorret BOOST_HOF_THIS or BOOST_HOF_CONST_THIS used.");
0195 };
0196 
0197 }}} // namespace boost::hof
0198 
0199 #endif
0200 
0201 
0202 #if BOOST_HOF_HAS_MANGLE_OVERLOAD
0203 
0204 #define BOOST_HOF_MANGLE_CAST(...) BOOST_HOF_REM
0205 
0206 #define BOOST_HOF_RETURNS_C_CAST(...) (__VA_ARGS__) BOOST_HOF_REM
0207 #define BOOST_HOF_RETURNS_REINTERPRET_CAST(...) reinterpret_cast<__VA_ARGS__>
0208 #define BOOST_HOF_RETURNS_STATIC_CAST(...) static_cast<__VA_ARGS__>
0209 #define BOOST_HOF_RETURNS_CONSTRUCT(...) __VA_ARGS__
0210 
0211 #else
0212 
0213 #define BOOST_HOF_RETURNS_DERAIL_MANGLE_CAST(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\
0214     BOOST_HOF_REM, \
0215     std::declval<__VA_ARGS__>() BOOST_HOF_EAT \
0216 )
0217 #define BOOST_HOF_MANGLE_CAST BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_DERAIL_MANGLE_CAST)
0218 
0219 
0220 #define BOOST_HOF_RETURNS_DERAIL_C_CAST(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\
0221     (__VA_ARGS__) BOOST_HOF_REM, \
0222     std::declval<__VA_ARGS__>() BOOST_HOF_EAT \
0223 )
0224 #define BOOST_HOF_RETURNS_C_CAST BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_DERAIL_C_CAST)
0225 
0226 
0227 #define BOOST_HOF_RETURNS_DERAIL_REINTERPRET_CAST(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\
0228     reinterpret_cast<__VA_ARGS__>, \
0229     std::declval<__VA_ARGS__>() BOOST_HOF_EAT \
0230 )
0231 #define BOOST_HOF_RETURNS_REINTERPRET_CAST BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_DERAIL_REINTERPRET_CAST)
0232 
0233 #define BOOST_HOF_RETURNS_DERAIL_STATIC_CAST(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\
0234     static_cast<__VA_ARGS__>, \
0235     std::declval<__VA_ARGS__>() BOOST_HOF_EAT \
0236 )
0237 #define BOOST_HOF_RETURNS_STATIC_CAST BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_DERAIL_STATIC_CAST)
0238 
0239 #define BOOST_HOF_RETURNS_DERAIL_CONSTRUCT(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\
0240     __VA_ARGS__, \
0241     std::declval<__VA_ARGS__>() BOOST_HOF_EAT \
0242 )
0243 #define BOOST_HOF_RETURNS_CONSTRUCT BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_DERAIL_CONSTRUCT)
0244 
0245 #endif
0246 
0247 #define BOOST_HOF_AUTO_FORWARD(...) BOOST_HOF_RETURNS_STATIC_CAST(decltype(__VA_ARGS__))(__VA_ARGS__)
0248 
0249 #endif