diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:12:59 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:12:59 +0900 |
commit | b8cf34c691623e4ec329053cbbf68522a855882d (patch) | |
tree | 34da08632a99677f6b79ecb65e5b655a5b69a67f /boost/hof/returns.hpp | |
parent | 3fdc3e5ee96dca5b11d1694975a65200787eab86 (diff) | |
download | boost-b8cf34c691623e4ec329053cbbf68522a855882d.tar.gz boost-b8cf34c691623e4ec329053cbbf68522a855882d.tar.bz2 boost-b8cf34c691623e4ec329053cbbf68522a855882d.zip |
Imported Upstream version 1.67.0upstream/1.67.0
Diffstat (limited to 'boost/hof/returns.hpp')
-rw-r--r-- | boost/hof/returns.hpp | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/boost/hof/returns.hpp b/boost/hof/returns.hpp new file mode 100644 index 0000000000..5360a38314 --- /dev/null +++ b/boost/hof/returns.hpp @@ -0,0 +1,249 @@ +/*============================================================================= + Copyright (c) 2014 Paul Fultz II + returns.h + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#ifndef BOOST_HOF_GUARD_RETURNS_H +#define BOOST_HOF_GUARD_RETURNS_H + +/// BOOST_HOF_RETURNS +/// =========== +/// +/// Description +/// ----------- +/// +/// The `BOOST_HOF_RETURNS` macro defines the function as the expression +/// equivalence. It does this by deducing `noexcept` and the return type by +/// using a trailing `decltype`. Instead of repeating the expression for the +/// return type, `noexcept` clause and the function body, this macro will +/// reduce the code duplication from that. +/// +/// Note: The expression used to deduce the return the type will also +/// constrain the template function and deduce `noexcept` as well, which is +/// different behaviour than using C++14's return type deduction. +/// +/// Synopsis +/// -------- +/// +/// #define BOOST_HOF_RETURNS(...) +/// +/// +/// Example +/// ------- +/// +/// #include <boost/hof.hpp> +/// #include <cassert> +/// +/// template<class T, class U> +/// auto sum(T x, U y) BOOST_HOF_RETURNS(x+y); +/// +/// int main() { +/// assert(3 == sum(1, 2)); +/// } +/// +/// +/// Incomplete this +/// --------------- +/// +/// Description +/// ----------- +/// +/// On some non-conformant compilers, such as gcc, the `this` variable cannot +/// be used inside the `BOOST_HOF_RETURNS` macro because it is considered an +/// incomplete type. So the following macros are provided to help workaround +/// the issue. +/// +/// +/// Synopsis +/// -------- +/// +/// // Declares the type of the `this` variable +/// #define BOOST_HOF_RETURNS_CLASS(...) +/// // Used to refer to the `this` variable in the BOOST_HOF_RETURNS macro +/// #define BOOST_HOF_THIS +/// // Used to refer to the const `this` variable in the BOOST_HOF_RETURNS macro +/// #define BOOST_HOF_CONST_THIS +/// +/// +/// Example +/// ------- +/// +/// #include <boost/hof.hpp> +/// #include <cassert> +/// +/// struct add_1 +/// { +/// int a; +/// add_1() : a(1) {} +/// +/// BOOST_HOF_RETURNS_CLASS(add_1); +/// +/// template<class T> +/// auto operator()(T x) const +/// BOOST_HOF_RETURNS(x+BOOST_HOF_CONST_THIS->a); +/// }; +/// +/// int main() { +/// assert(3 == add_1()(2)); +/// } +/// +/// +/// Mangling overloads +/// ------------------ +/// +/// Description +/// ----------- +/// +/// On older compilers some operations done in the expressions cannot be +/// properly mangled. These macros help provide workarounds for these +/// operations on older compilers. +/// +/// +/// Synopsis +/// -------- +/// +/// // Explicitly defines the type for name mangling +/// #define BOOST_HOF_MANGLE_CAST(...) +/// // C cast for name mangling +/// #define BOOST_HOF_RETURNS_C_CAST(...) +/// // Reinterpret cast for name mangling +/// #define BOOST_HOF_RETURNS_REINTERPRET_CAST(...) +/// // Static cast for name mangling +/// #define BOOST_HOF_RETURNS_STATIC_CAST(...) +/// // Construction for name mangling +/// #define BOOST_HOF_RETURNS_CONSTRUCT(...) +/// + + +#include <boost/hof/config.hpp> +#include <utility> +#include <boost/hof/detail/forward.hpp> +#include <boost/hof/detail/noexcept.hpp> + +#define BOOST_HOF_EAT(...) +#define BOOST_HOF_REM(...) __VA_ARGS__ + +#if BOOST_HOF_HAS_COMPLETE_DECLTYPE && BOOST_HOF_HAS_MANGLE_OVERLOAD +#ifdef _MSC_VER +// Since decltype can't be used in noexcept on MSVC, we can't check for noexcept +// move constructors. +#define BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(...) BOOST_HOF_NOEXCEPT(noexcept(__VA_ARGS__)) +#else +#define BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(...) BOOST_HOF_NOEXCEPT(noexcept(static_cast<decltype(__VA_ARGS__)>(__VA_ARGS__))) +#endif +#define BOOST_HOF_RETURNS(...) \ +BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(__VA_ARGS__) \ +-> decltype(__VA_ARGS__) { return __VA_ARGS__; } +#define BOOST_HOF_THIS this +#define BOOST_HOF_CONST_THIS this +#define BOOST_HOF_RETURNS_CLASS(...) \ +void fit_returns_class_check() \ +{ \ + static_assert(std::is_same<__VA_ARGS__*, decltype(this)>::value, \ + "Returns class " #__VA_ARGS__ " type doesn't match"); \ +} + +#define BOOST_HOF_MANGLE_CAST(...) BOOST_HOF_REM + +#define BOOST_HOF_RETURNS_C_CAST(...) (__VA_ARGS__) BOOST_HOF_REM +#define BOOST_HOF_RETURNS_REINTERPRET_CAST(...) reinterpret_cast<__VA_ARGS__> +#define BOOST_HOF_RETURNS_STATIC_CAST(...) static_cast<__VA_ARGS__> +#define BOOST_HOF_RETURNS_CONSTRUCT(...) __VA_ARGS__ +#else +#include <boost/hof/detail/pp.hpp> + +#define BOOST_HOF_RETURNS_RETURN(...) return BOOST_HOF_RETURNS_RETURN_X(BOOST_HOF_PP_WALL(__VA_ARGS__)) +#define BOOST_HOF_RETURNS_RETURN_X(...) __VA_ARGS__ + +#ifdef _MSC_VER +// Since decltype can't be used in noexcept on MSVC, we can't check for noexcept +// move constructors. +#define BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(...) BOOST_HOF_NOEXCEPT(noexcept(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(__VA_ARGS__))) +#else +#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__)))) +#endif + +#define BOOST_HOF_RETURNS_DECLTYPE(...) \ +-> decltype(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(__VA_ARGS__)) + +#define BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(...) BOOST_HOF_RETURNS_DECLTYPE_CONTEXT_X(BOOST_HOF_PP_WALL(__VA_ARGS__)) +#define BOOST_HOF_RETURNS_DECLTYPE_CONTEXT_X(...) __VA_ARGS__ + +#define BOOST_HOF_RETURNS_THAT(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\ + (boost::hof::detail::check_this<__VA_ARGS__, decltype(this)>(), this), \ + std::declval<__VA_ARGS__>() \ +) + +#define BOOST_HOF_THIS BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_THAT)(fit_this_type) +#define BOOST_HOF_CONST_THIS BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_THAT)(fit_const_this_type) + +#define BOOST_HOF_RETURNS_CLASS(...) typedef __VA_ARGS__* fit_this_type; typedef const __VA_ARGS__* fit_const_this_type + +#define BOOST_HOF_RETURNS(...) \ +BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT(__VA_ARGS__) \ +BOOST_HOF_RETURNS_DECLTYPE(__VA_ARGS__) \ +{ BOOST_HOF_RETURNS_RETURN(__VA_ARGS__); } + + +namespace boost { namespace hof { namespace detail { +template<class Assumed, class T> +struct check_this +{ + static_assert(std::is_same<T, Assumed>::value, "Incorret BOOST_HOF_THIS or BOOST_HOF_CONST_THIS used."); +}; + +}}} // namespace boost::hof + +#endif + + +#if BOOST_HOF_HAS_MANGLE_OVERLOAD + +#define BOOST_HOF_MANGLE_CAST(...) BOOST_HOF_REM + +#define BOOST_HOF_RETURNS_C_CAST(...) (__VA_ARGS__) BOOST_HOF_REM +#define BOOST_HOF_RETURNS_REINTERPRET_CAST(...) reinterpret_cast<__VA_ARGS__> +#define BOOST_HOF_RETURNS_STATIC_CAST(...) static_cast<__VA_ARGS__> +#define BOOST_HOF_RETURNS_CONSTRUCT(...) __VA_ARGS__ + +#else + +#define BOOST_HOF_RETURNS_DERAIL_MANGLE_CAST(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\ + BOOST_HOF_REM, \ + std::declval<__VA_ARGS__>() BOOST_HOF_EAT \ +) +#define BOOST_HOF_MANGLE_CAST BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_DERAIL_MANGLE_CAST) + + +#define BOOST_HOF_RETURNS_DERAIL_C_CAST(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\ + (__VA_ARGS__) BOOST_HOF_REM, \ + std::declval<__VA_ARGS__>() BOOST_HOF_EAT \ +) +#define BOOST_HOF_RETURNS_C_CAST BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_DERAIL_C_CAST) + + +#define BOOST_HOF_RETURNS_DERAIL_REINTERPRET_CAST(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\ + reinterpret_cast<__VA_ARGS__>, \ + std::declval<__VA_ARGS__>() BOOST_HOF_EAT \ +) +#define BOOST_HOF_RETURNS_REINTERPRET_CAST BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_DERAIL_REINTERPRET_CAST) + +#define BOOST_HOF_RETURNS_DERAIL_STATIC_CAST(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\ + static_cast<__VA_ARGS__>, \ + std::declval<__VA_ARGS__>() BOOST_HOF_EAT \ +) +#define BOOST_HOF_RETURNS_STATIC_CAST BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_DERAIL_STATIC_CAST) + +#define BOOST_HOF_RETURNS_DERAIL_CONSTRUCT(...) BOOST_HOF_PP_IIF(BOOST_HOF_PP_IS_PAREN(BOOST_HOF_RETURNS_DECLTYPE_CONTEXT(())))(\ + __VA_ARGS__, \ + std::declval<__VA_ARGS__>() BOOST_HOF_EAT \ +) +#define BOOST_HOF_RETURNS_CONSTRUCT BOOST_HOF_PP_RAIL(BOOST_HOF_RETURNS_DERAIL_CONSTRUCT) + +#endif + +#define BOOST_HOF_AUTO_FORWARD(...) BOOST_HOF_RETURNS_STATIC_CAST(decltype(__VA_ARGS__))(__VA_ARGS__) + +#endif |