/* @Copyright Barrett Adair 2015-2017 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_CLBL_TRTS_DETAIL_UTILITY_HPP #define BOOST_CLBL_TRTS_DETAIL_UTILITY_HPP #include #include #include namespace boost { namespace callable_traits { namespace detail { struct cdecl_tag{}; struct stdcall_tag{}; struct fastcall_tag{}; struct pascal_tag{}; struct invalid_type { invalid_type() = delete; }; struct reference_error { reference_error() = delete; }; template using error_type = typename std::conditional< std::is_reference::value, reference_error, invalid_type>::type; #ifdef BOOST_CLBL_TRTS_DISABLE_ABOMINABLE_FUNCTIONS struct abominable_functions_not_supported_on_this_compiler{}; #endif // used to convey "this type doesn't matter" in code struct dummy {}; // used as return type in failed SFINAE tests struct substitution_failure : std::false_type{}; template using bool_type = std::integral_constant; // shorthand for std::tuple_element template using at = typename std::tuple_element::type; template using add_member_pointer = T Class::*; template using fail_when_same = fail_if::value, ErrorType>; template::type> using try_but_fail_if_invalid = sfinae_try, fail_when_same>; template::type, bool is_reference_error = std::is_same::value> using fail_if_invalid = fail_if< std::is_same::value || is_reference_error, typename std::conditional::type>; template using fallback_if_invalid = typename std::conditional< std::is_same::value, Fallback, T>::type; template class Alias, typename U = Alias> struct force_sfinae { using type = U; }; template using shallow_decay = typename std::remove_cv< typename std::remove_reference::type>::type; template struct is_reference_wrapper_t { using type = std::false_type; }; template struct is_reference_wrapper_t> { using type = std::true_type; }; template using is_reference_wrapper = typename is_reference_wrapper_t>::type; template struct unwrap_reference_t { using type = T; }; template struct unwrap_reference_t> { using type = decltype(std::declval().get()); }; // removes std::reference_wrapper template using unwrap_reference = typename unwrap_reference_t::type; }}} // namespace boost::callable_traits::detail #endif // #ifndef BOOST_CLBL_TRTS_DETAIL_UTILITY_HPP