mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Improve implementation of traits for functions
This commit is contained in:
parent
57c50fce89
commit
31b658ba81
@ -21,7 +21,7 @@ copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
FITNESS FOR TArgs PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
@ -36,101 +36,251 @@ SOFTWARE.
|
||||
#include "type_traits.h"
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// A template to extract the function type traits.
|
||||
// Primary template (unspecialized)
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
template <typename T, typename Enable = void>
|
||||
struct function_traits;
|
||||
|
||||
//***************************************************************************
|
||||
/// Specialisation for function pointers
|
||||
// Base for plain function type TReturn(TArgs...)
|
||||
//***************************************************************************
|
||||
template <typename TReturn, typename... TArgs>
|
||||
struct function_traits<TReturn(*)(TArgs...)>
|
||||
struct function_traits<TReturn(TArgs...), void>
|
||||
{
|
||||
using function_type = TReturn(TArgs...); ///< The signature of the function.
|
||||
using return_type = TReturn; ///< The return type.
|
||||
using object_type = void; ///< The object type, if a member function.
|
||||
using argument_types = etl::type_list<TArgs...>; ///< An etl::type_list containing the function argument types.
|
||||
public:
|
||||
|
||||
static constexpr bool is_function = true; ///< <b>true</b> if the type is a free, static or global function, otherwise <b>false</b>.
|
||||
static constexpr bool is_member_function = false; ///< <b>true</b> if the type is a member function, otherwise <b>false</b>.
|
||||
static constexpr bool is_const = false; ///< <b>true</b> if the type is a const member function, otherwise <b>false</b>.
|
||||
static constexpr size_t argument_count = sizeof...(TArgs); ///< The number of arguments that the function takes.
|
||||
using function_type = TReturn(TArgs...);
|
||||
using return_type = TReturn;
|
||||
using object_type = void;
|
||||
using argument_types = etl::type_list<TArgs...>;
|
||||
|
||||
static constexpr bool is_function = true;
|
||||
static constexpr bool is_member_function = false;
|
||||
static constexpr bool is_functor = false;
|
||||
static constexpr bool is_const = false;
|
||||
static constexpr bool is_volatile = false;
|
||||
static constexpr bool is_noexcept = false;
|
||||
static constexpr size_t arity = sizeof...(TArgs);
|
||||
|
||||
ETL_DEPRECATED_REASON("Use etl::function_traits::arity instead")
|
||||
static constexpr size_t argument_count = arity;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// Free function pointer
|
||||
//***************************************************************************
|
||||
template <typename TReturn, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(*)(TArgs...)>::is_function;
|
||||
|
||||
template <typename TReturn, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(*)(TArgs...)>::is_member_function;
|
||||
|
||||
template <typename TReturn, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(*)(TArgs...)>::is_const;
|
||||
|
||||
template <typename TReturn, typename... TArgs>
|
||||
constexpr size_t function_traits<TReturn(*)(TArgs...)>::argument_count;
|
||||
struct function_traits<TReturn(*)(TArgs...), void> : function_traits<TReturn(TArgs...)> {};
|
||||
|
||||
//***************************************************************************
|
||||
/// Specialisation for member function pointers
|
||||
// Free function reference
|
||||
//***************************************************************************
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
struct function_traits<TReturn(TObject::*)(TArgs...)>
|
||||
template <typename TReturn, typename... TArgs>
|
||||
struct function_traits<TReturn(&)(TArgs...), void> : function_traits<TReturn(TArgs...)> {};
|
||||
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
//***************************************************************************
|
||||
// Free noexcept function pointer
|
||||
//***************************************************************************
|
||||
template <typename TReturn, typename... TArgs>
|
||||
struct function_traits<TReturn(*)(TArgs...) noexcept, void> : function_traits<TReturn(TArgs...)>
|
||||
{
|
||||
using function_type = TReturn(TArgs...); ///< The signature of the function.
|
||||
using return_type = TReturn; ///< The return type.
|
||||
using object_type = TObject; ///< The object type, if a member function.
|
||||
using argument_types = etl::type_list<TArgs...>; ///< An etl::type_list containing the function argument types.
|
||||
|
||||
static constexpr bool is_function = false; ///< <b>true</b> if the type is a free, static or global function, otherwise <b>false</b>.
|
||||
static constexpr bool is_member_function = true; ///< <b>true</b> if the type is a member function, otherwise <b>false</b>.
|
||||
static constexpr bool is_const = false; ///< <b>true</b> if the type is a const member function, otherwise <b>false</b>.
|
||||
static constexpr size_t argument_count = sizeof...(TArgs); ///< The number of arguments that the function takes.
|
||||
static constexpr bool is_noexcept = true;
|
||||
};
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TObject::*)(TArgs...)>::is_function;
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TObject::*)(TArgs...)>::is_member_function;
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TObject::*)(TArgs...)>::is_const;
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr size_t function_traits<TReturn(TObject::*)(TArgs...)>::argument_count;
|
||||
|
||||
//***************************************************************************
|
||||
/// Specialisation for const member function pointers
|
||||
// Free noexcept function reference.
|
||||
//***************************************************************************
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
struct function_traits<TReturn(TObject::*)(TArgs...) const>
|
||||
template <typename TReturn, typename... TArgs>
|
||||
struct function_traits<TReturn(&)(TArgs...) noexcept, void> : function_traits<TReturn(TArgs...)>
|
||||
{
|
||||
using function_type = TReturn(TArgs...); ///< The signature of the function.
|
||||
using return_type = TReturn; ///< The return type.
|
||||
using object_type = TObject; ///< The object type, if a member function.
|
||||
using argument_types = etl::type_list<TArgs...>; ///< An etl::type_list containing the function argument types.
|
||||
static constexpr bool is_noexcept = true;
|
||||
};
|
||||
#endif
|
||||
|
||||
static constexpr bool is_function = false; ///< <b>true</b> if the type is a free, static or global function, otherwise <b>false</b>.
|
||||
static constexpr bool is_member_function = true; ///< <b>true</b> if the type is a member function, otherwise <b>false</b>.
|
||||
static constexpr bool is_const = true; ///< <b>true</b> if the type is a const member function, otherwise <b>false</b>.
|
||||
static constexpr size_t argument_count = sizeof...(TArgs); ///< The number of arguments that the function takes.
|
||||
//***************************************************************************
|
||||
// Member function pointers
|
||||
//***************************************************************************
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
struct function_traits<TReturn (TObject::*)(TArgs...), void> : function_traits<TReturn(TArgs...)>
|
||||
{
|
||||
using object_type = TObject;
|
||||
static constexpr bool is_function = false;
|
||||
static constexpr bool is_member_function = true;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// Const member function pointers
|
||||
//***************************************************************************
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TObject::*)(TArgs...) const>::is_function;
|
||||
struct function_traits<TReturn (TObject::*)(TArgs...) const, void> : function_traits<TReturn(TObject::*)(TArgs...)>
|
||||
{
|
||||
static constexpr bool is_const = true;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// Volatile member function pointers
|
||||
//***************************************************************************
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
struct function_traits<TReturn (TObject::*)(TArgs...) volatile, void> : function_traits<TReturn(TObject::*)(TArgs...)>
|
||||
{
|
||||
static constexpr bool is_volatile = true;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// Const volatile member function pointers
|
||||
//***************************************************************************
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
struct function_traits<TReturn (TObject::*)(TArgs...) const volatile, void> : function_traits<TReturn(TObject::*)(TArgs...)>
|
||||
{
|
||||
static constexpr bool is_const = true;
|
||||
static constexpr bool is_volatile = true;
|
||||
};
|
||||
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
//***************************************************************************
|
||||
// Noexcept member function pointers
|
||||
//***************************************************************************
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
struct function_traits<TReturn (TObject::*)(TArgs...) noexcept, void> : function_traits<TReturn(TObject::*)(TArgs...)>
|
||||
{
|
||||
static constexpr bool is_noexcept = true;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// Const noexcept member function pointers
|
||||
//***************************************************************************
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
struct function_traits<TReturn (TObject::*)(TArgs...) const noexcept, void> : function_traits<TReturn(TObject::*)(TArgs...) const>
|
||||
{
|
||||
static constexpr bool is_noexcept = true;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// Volatile noexcept member function pointers
|
||||
//***************************************************************************
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
struct function_traits<TReturn (TObject::*)(TArgs...) volatile noexcept, void> : function_traits<TReturn(TObject::*)(TArgs...) volatile>
|
||||
{
|
||||
static constexpr bool is_noexcept = true;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// Const volatile noexcept member function pointers
|
||||
//***************************************************************************
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
struct function_traits<TReturn (TObject::*)(TArgs...) const volatile noexcept, void> : function_traits<TReturn(TObject::*)(TArgs...) const volatile>
|
||||
{
|
||||
static constexpr bool is_noexcept = true;
|
||||
};
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
// Forward cv/ref on the whole type to the unqualified type.
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
struct function_traits<T, etl::enable_if_t<!etl::is_same<T, etl::remove_cvref_t<T>>::value &&
|
||||
!etl::is_class<etl::decay_t<T>>::value>>
|
||||
: function_traits<etl::remove_cvref_t<T>>
|
||||
{
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// Functors / lambdas: enable only for class types that have a unique operator()
|
||||
//***************************************************************************
|
||||
namespace private_function_traits
|
||||
{
|
||||
//*********************************
|
||||
// Helper to get pointer to call operator
|
||||
//*********************************
|
||||
template <typename U>
|
||||
using call_operator_ptr_t = decltype(&U::operator());
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Functors / lambdas specialisation
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
struct function_traits<T, etl::enable_if_t<etl::is_class<etl::decay_t<T>>::value&&
|
||||
etl::has_unique_call_operator<T>::value>>
|
||||
: function_traits<private_function_traits::call_operator_ptr_t<etl::decay_t<T>> >
|
||||
{
|
||||
static constexpr bool is_functor = true;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// Out-of-class definitions for the function_traits static members
|
||||
//***************************************************************************
|
||||
// free/function primary template
|
||||
template <typename TReturn, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TArgs...), void>::is_function;
|
||||
|
||||
template <typename TReturn, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TArgs...), void>::is_member_function;
|
||||
|
||||
template <typename TReturn, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TArgs...), void>::is_functor;
|
||||
|
||||
template <typename TReturn, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TArgs...), void>::is_const;
|
||||
|
||||
template <typename TReturn, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TArgs...), void>::is_volatile;
|
||||
|
||||
template <typename TReturn, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TArgs...), void>::is_noexcept;
|
||||
|
||||
template <typename TReturn, typename... TArgs>
|
||||
constexpr size_t function_traits<TReturn(TArgs...), void>::arity;
|
||||
|
||||
// member-function-pointer specialization
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn (TObject::*)(TArgs...), void>::is_function;
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TObject::*)(TArgs...) const>::is_member_function;
|
||||
constexpr bool function_traits<TReturn (TObject::*)(TArgs...), void>::is_member_function;
|
||||
|
||||
// cv/ref-qualified member-function pointer flags
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn (TObject::*)(TArgs...) const, void>::is_const;
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn (TObject::*)(TArgs...) volatile, void>::is_volatile;
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn (TObject::*)(TArgs...) const volatile, void>::is_const;
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn (TObject::*)(TArgs...) const volatile, void>::is_volatile;
|
||||
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
template <typename TReturn, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(*)(TArgs...) noexcept, void>::is_noexcept;
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn(TObject::*)(TArgs...) const>::is_const;
|
||||
constexpr bool function_traits<TReturn (TObject::*)(TArgs...) noexcept, void>::is_noexcept;
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr size_t function_traits<TReturn(TObject::*)(TArgs...) const>::argument_count;
|
||||
constexpr bool function_traits<TReturn (TObject::*)(TArgs...) const noexcept, void>::is_noexcept;
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn (TObject::*)(TArgs...) volatile noexcept, void>::is_noexcept;
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs>
|
||||
constexpr bool function_traits<TReturn (TObject::*)(TArgs...) const volatile noexcept, void>::is_noexcept;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
// Functor / lambda specialisation: provide out-of-class definition for is_functor
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
constexpr bool function_traits<T, etl::enable_if_t<etl::is_class<etl::decay_t<T>>::value &&
|
||||
etl::has_unique_call_operator<T>::value>>::is_functor;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -2571,10 +2571,13 @@ typedef integral_constant<bool, true> true_type;
|
||||
// Plain / cv-qualified
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs...)> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs...) const> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs...) volatile> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs...) const volatile> : etl::true_type {};
|
||||
|
||||
@ -2582,18 +2585,41 @@ typedef integral_constant<bool, true> true_type;
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs..., ...)> : etl::true_type {};
|
||||
|
||||
// noexcept variants (if supported by the toolchain)
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs..., ...) const> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs..., ...) volatile> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs..., ...) const volatile> : etl::true_type {};
|
||||
|
||||
// noexcept variants (if supported)
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs...) noexcept> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs...) const noexcept> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs...) volatile noexcept> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs...) const volatile noexcept> : etl::true_type {};
|
||||
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs..., ...) noexcept> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs..., ...) const noexcept> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs..., ...) volatile noexcept> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs..., ...) const volatile noexcept> : etl::true_type {};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
@ -2679,26 +2705,74 @@ typedef integral_constant<bool, true> true_type;
|
||||
//***************************************************************************
|
||||
/// Is T a member function pointer
|
||||
//***************************************************************************
|
||||
namespace private_type_traits
|
||||
{
|
||||
// Primary: not a member function pointer.
|
||||
template <typename T>
|
||||
struct is_member_function_pointer_helper : etl::false_type
|
||||
{
|
||||
};
|
||||
template <typename T> struct is_member_function_pointer : etl::false_type {};
|
||||
|
||||
// If the type is 'TMember TObject::*' then TMember is the member
|
||||
// Uses etl::is_function<TMember> to detect member function pointers.
|
||||
template <typename TMember, typename TObject>
|
||||
struct is_member_function_pointer_helper<TMember TObject::*> : etl::is_function<TMember>
|
||||
{
|
||||
};
|
||||
}
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...)> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) volatile> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const volatile> : etl::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_member_function_pointer : private_type_traits::is_member_function_pointer_helper<etl::remove_cv_t<T>>
|
||||
{
|
||||
};
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) volatile noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const volatile noexcept> : etl::true_type {};
|
||||
#endif
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) &> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const &> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) volatile &> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const volatile &> : etl::true_type {};
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) &&> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const &&> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) volatile &&> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const volatile &&>: etl::true_type {};
|
||||
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) & noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const & noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) volatile & noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const volatile & noexcept> : etl::true_type {};
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) && noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const && noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) volatile && noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const volatile && noexcept>: etl::true_type {};
|
||||
#endif
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...)> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) volatile> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const volatile> : etl::true_type {};
|
||||
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) volatile noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const volatile noexcept> : etl::true_type {};
|
||||
#endif
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) &> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const &> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) volatile &> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const volatile &> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) &&> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const &&> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) volatile &&> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const volatile &&>: etl::true_type {};
|
||||
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) & noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const & noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) volatile & noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const volatile & noexcept> : etl::true_type {};
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) && noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const && noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) volatile && noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const volatile && noexcept>: etl::true_type {};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
|
||||
@ -325,6 +325,16 @@ SOFTWARE.
|
||||
#define ETL_HAS_CHRONO_LITERALS_DURATION 1
|
||||
#endif
|
||||
|
||||
//*************************************
|
||||
// Indicate if noexcept is part of the function type.
|
||||
#if !defined(ETL_HAS_NOEXCEPT_FUNCTION_TYPE)
|
||||
#if defined(__cpp_noexcept_function_type) && (__cpp_noexcept_function_type >= 201510)
|
||||
#define ETL_HAS_NOEXCEPT_FUNCTION_TYPE 1
|
||||
#else
|
||||
#define ETL_HAS_NOEXCEPT_FUNCTION_TYPE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//*************************************
|
||||
// The macros below are dependent on the profile.
|
||||
// C++11
|
||||
@ -652,6 +662,7 @@ namespace etl
|
||||
static ETL_CONSTANT bool has_chrono_literals_microseconds = (ETL_HAS_CHRONO_LITERALS_DURATION == 1);
|
||||
static ETL_CONSTANT bool has_chrono_literals_nanoseconds = (ETL_HAS_CHRONO_LITERALS_DURATION == 1);
|
||||
static ETL_CONSTANT bool has_std_byteswap = (ETL_HAS_STD_BYTESWAP == 1);
|
||||
static ETL_CONSTANT bool has_noexcept_function_type = (ETL_HAS_NOEXCEPT_FUNCTION_TYPE == 1);
|
||||
|
||||
// Is...
|
||||
static ETL_CONSTANT bool is_debug_build = (ETL_IS_DEBUG_BUILD == 1);
|
||||
|
||||
@ -2564,10 +2564,13 @@ typedef integral_constant<bool, true> true_type;
|
||||
// Plain / cv-qualified
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs...)> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs...) const> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs...) volatile> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs...) const volatile> : etl::true_type {};
|
||||
|
||||
@ -2575,18 +2578,41 @@ typedef integral_constant<bool, true> true_type;
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs..., ...)> : etl::true_type {};
|
||||
|
||||
// noexcept variants (if supported by the toolchain)
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs..., ...) const> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs..., ...) volatile> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs..., ...) const volatile> : etl::true_type {};
|
||||
|
||||
// noexcept variants (if supported)
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs...) noexcept> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs...) const noexcept> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs...) volatile noexcept> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs...) const volatile noexcept> : etl::true_type {};
|
||||
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs..., ...) noexcept> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs..., ...) const noexcept> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs..., ...) volatile noexcept> : etl::true_type {};
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
struct is_function<TReturn(TArgs..., ...) const volatile noexcept> : etl::true_type {};
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
@ -2672,26 +2698,74 @@ typedef integral_constant<bool, true> true_type;
|
||||
//***************************************************************************
|
||||
/// Is T a member function pointer
|
||||
//***************************************************************************
|
||||
namespace private_type_traits
|
||||
{
|
||||
// Primary: not a member function pointer.
|
||||
template <typename T>
|
||||
struct is_member_function_pointer_helper : etl::false_type
|
||||
{
|
||||
};
|
||||
template <typename T> struct is_member_function_pointer : etl::false_type {};
|
||||
|
||||
// If the type is 'TMember TObject::*' then TMember is the member
|
||||
// Uses etl::is_function<TMember> to detect member function pointers.
|
||||
template <typename TMember, typename TObject>
|
||||
struct is_member_function_pointer_helper<TMember TObject::*> : etl::is_function<TMember>
|
||||
{
|
||||
};
|
||||
}
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...)> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) volatile> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const volatile> : etl::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_member_function_pointer : private_type_traits::is_member_function_pointer_helper<etl::remove_cv_t<T>>
|
||||
{
|
||||
};
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) volatile noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const volatile noexcept> : etl::true_type {};
|
||||
#endif
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) &> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const &> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) volatile &> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const volatile &> : etl::true_type {};
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) &&> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const &&> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) volatile &&> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const volatile &&>: etl::true_type {};
|
||||
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) & noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const & noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) volatile & noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const volatile & noexcept> : etl::true_type {};
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) && noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const && noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) volatile && noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs...) const volatile && noexcept>: etl::true_type {};
|
||||
#endif
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...)> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) volatile> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const volatile> : etl::true_type {};
|
||||
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) volatile noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const volatile noexcept> : etl::true_type {};
|
||||
#endif
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) &> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const &> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) volatile &> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const volatile &> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) &&> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const &&> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) volatile &&> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const volatile &&>: etl::true_type {};
|
||||
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) & noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const & noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) volatile & noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const volatile & noexcept> : etl::true_type {};
|
||||
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) && noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const && noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) volatile && noexcept> : etl::true_type {};
|
||||
template <typename TReturn, typename TObject, typename... TArgs> struct is_member_function_pointer<TReturn(TObject::*)(TArgs..., ...) const volatile && noexcept>: etl::true_type {};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP17
|
||||
|
||||
@ -42,6 +42,13 @@ namespace
|
||||
{
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// The free noexcept function taking no parameters.
|
||||
//*****************************************************************************
|
||||
void free_void_noexcept() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// The free function taking an int parameter.
|
||||
//*****************************************************************************
|
||||
@ -67,6 +74,30 @@ namespace
|
||||
{
|
||||
}
|
||||
|
||||
void member_void_noexcept() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
void member_void_const_noexcept() const noexcept
|
||||
{
|
||||
}
|
||||
|
||||
void member_void_volatile() volatile
|
||||
{
|
||||
}
|
||||
|
||||
void member_void_volatile_noexcept() volatile noexcept
|
||||
{
|
||||
}
|
||||
|
||||
void member_void_const_volatile() const volatile
|
||||
{
|
||||
}
|
||||
|
||||
void member_void_const_volatile_noexcept() const volatile noexcept
|
||||
{
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
// int
|
||||
int member_int(int i, int j)
|
||||
@ -86,6 +117,16 @@ namespace
|
||||
(void)j;
|
||||
}
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// A functor with a unique operator()
|
||||
//*****************************************************************************
|
||||
struct Functor { int operator()(int x) { return x + 1; } };
|
||||
|
||||
//*****************************************************************************
|
||||
// A functor with a unique operator()
|
||||
//*****************************************************************************
|
||||
struct FunctorConst { int operator()(int x) const { return x + 1; } };
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -106,8 +147,30 @@ namespace
|
||||
|
||||
CHECK_TRUE(traits::is_function);
|
||||
CHECK_FALSE(traits::is_member_function);
|
||||
CHECK_FALSE(traits::is_functor);
|
||||
CHECK_FALSE(traits::is_const);
|
||||
CHECK_EQUAL(0, traits::argument_count);
|
||||
CHECK_FALSE(traits::is_volatile);
|
||||
CHECK_FALSE(traits::is_noexcept);
|
||||
CHECK_EQUAL(0, traits::arity);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_free_function_free_void_noexcept)
|
||||
{
|
||||
free_void_noexcept(); // Keep clang happy
|
||||
|
||||
using traits = etl::function_traits<decltype(&free_void_noexcept)>;
|
||||
|
||||
CHECK_TRUE((std::is_same<void(void), traits::function_type>::value));
|
||||
CHECK_TRUE((std::is_same<void, traits::return_type>::value));
|
||||
CHECK_TRUE((std::is_same<void, traits::object_type>::value));
|
||||
CHECK_TRUE((std::is_same<etl::type_list<>, traits::argument_types>::value));
|
||||
|
||||
CHECK_TRUE(traits::is_function);
|
||||
CHECK_FALSE(traits::is_member_function);
|
||||
CHECK_FALSE(traits::is_functor);
|
||||
CHECK_FALSE(traits::is_const);
|
||||
CHECK_FALSE(traits::is_volatile);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -124,8 +187,11 @@ namespace
|
||||
|
||||
CHECK_TRUE(traits::is_function);
|
||||
CHECK_FALSE(traits::is_member_function);
|
||||
CHECK_FALSE(traits::is_functor);
|
||||
CHECK_FALSE(traits::is_const);
|
||||
CHECK_EQUAL(2 , traits::argument_count);
|
||||
CHECK_FALSE(traits::is_volatile);
|
||||
CHECK_FALSE(traits::is_noexcept);
|
||||
CHECK_EQUAL(2, traits::arity);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -140,8 +206,11 @@ namespace
|
||||
|
||||
CHECK_FALSE(traits::is_function);
|
||||
CHECK_TRUE(traits::is_member_function);
|
||||
CHECK_FALSE(traits::is_functor);
|
||||
CHECK_FALSE(traits::is_const);
|
||||
CHECK_EQUAL(0, traits::argument_count);
|
||||
CHECK_FALSE(traits::is_volatile);
|
||||
CHECK_FALSE(traits::is_noexcept);
|
||||
CHECK_EQUAL(0, traits::arity);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -156,8 +225,141 @@ namespace
|
||||
|
||||
CHECK_FALSE(traits::is_function);
|
||||
CHECK_TRUE(traits::is_member_function);
|
||||
CHECK_FALSE(traits::is_functor);
|
||||
CHECK_TRUE(traits::is_const);
|
||||
CHECK_EQUAL(0, traits::argument_count);
|
||||
CHECK_FALSE(traits::is_volatile);
|
||||
CHECK_FALSE(traits::is_noexcept);
|
||||
CHECK_EQUAL(0, traits::arity);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_member_function_void_noexcept)
|
||||
{
|
||||
using traits = etl::function_traits<decltype(&Object::member_void_noexcept)>;
|
||||
|
||||
CHECK_TRUE((std::is_same<void(void), traits::function_type>::value));
|
||||
CHECK_TRUE((std::is_same<void, traits::return_type>::value));
|
||||
CHECK_TRUE((std::is_same<Object, traits::object_type>::value));
|
||||
CHECK_TRUE((std::is_same<etl::type_list<>, traits::argument_types>::value));
|
||||
|
||||
CHECK_FALSE(traits::is_function);
|
||||
CHECK_TRUE(traits::is_member_function);
|
||||
CHECK_FALSE(traits::is_functor);
|
||||
CHECK_FALSE(traits::is_const);
|
||||
CHECK_FALSE(traits::is_volatile);
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
CHECK_TRUE(traits::is_noexcept);
|
||||
#else
|
||||
CHECK_FALSE(traits::is_noexcept);
|
||||
#endif
|
||||
CHECK_EQUAL(0, traits::arity);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_member_function_void_const_noexcept)
|
||||
{
|
||||
using traits = etl::function_traits<decltype(&Object::member_void_const_noexcept)>;
|
||||
|
||||
CHECK_TRUE((std::is_same<void(void), traits::function_type>::value));
|
||||
CHECK_TRUE((std::is_same<void, traits::return_type>::value));
|
||||
CHECK_TRUE((std::is_same<Object, traits::object_type>::value));
|
||||
CHECK_TRUE((std::is_same<etl::type_list<>, traits::argument_types>::value));
|
||||
|
||||
CHECK_FALSE(traits::is_function);
|
||||
CHECK_TRUE(traits::is_member_function);
|
||||
CHECK_FALSE(traits::is_functor);
|
||||
CHECK_TRUE(traits::is_const);
|
||||
CHECK_FALSE(traits::is_volatile);
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
CHECK_TRUE(traits::is_noexcept);
|
||||
#else
|
||||
CHECK_FALSE(traits::is_noexcept);
|
||||
#endif
|
||||
CHECK_EQUAL(0, traits::arity);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_member_function_void_volatile)
|
||||
{
|
||||
using traits = etl::function_traits<decltype(&Object::member_void_volatile)>;
|
||||
|
||||
CHECK_TRUE((std::is_same<void(void), traits::function_type>::value));
|
||||
CHECK_TRUE((std::is_same<void, traits::return_type>::value));
|
||||
CHECK_TRUE((std::is_same<Object, traits::object_type>::value));
|
||||
CHECK_TRUE((std::is_same<etl::type_list<>, traits::argument_types>::value));
|
||||
|
||||
CHECK_FALSE(traits::is_function);
|
||||
CHECK_TRUE(traits::is_member_function);
|
||||
CHECK_FALSE(traits::is_functor);
|
||||
CHECK_FALSE(traits::is_const);
|
||||
CHECK_TRUE(traits::is_volatile);
|
||||
CHECK_FALSE(traits::is_noexcept);
|
||||
CHECK_EQUAL(0, traits::arity);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_member_function_void_const_volatile)
|
||||
{
|
||||
using traits = etl::function_traits<decltype(&Object::member_void_const_volatile)>;
|
||||
|
||||
CHECK_TRUE((std::is_same<void(void), traits::function_type>::value));
|
||||
CHECK_TRUE((std::is_same<void, traits::return_type>::value));
|
||||
CHECK_TRUE((std::is_same<Object, traits::object_type>::value));
|
||||
CHECK_TRUE((std::is_same<etl::type_list<>, traits::argument_types>::value));
|
||||
|
||||
CHECK_FALSE(traits::is_function);
|
||||
CHECK_TRUE(traits::is_member_function);
|
||||
CHECK_FALSE(traits::is_functor);
|
||||
CHECK_TRUE(traits::is_const);
|
||||
CHECK_TRUE(traits::is_volatile);
|
||||
CHECK_FALSE(traits::is_noexcept);
|
||||
CHECK_EQUAL(0, traits::arity);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_member_function_void_volatile_noexcept)
|
||||
{
|
||||
using traits = etl::function_traits<decltype(&Object::member_void_volatile_noexcept)>;
|
||||
|
||||
CHECK_TRUE((std::is_same<void(void), traits::function_type>::value));
|
||||
CHECK_TRUE((std::is_same<void, traits::return_type>::value));
|
||||
CHECK_TRUE((std::is_same<Object, traits::object_type>::value));
|
||||
CHECK_TRUE((std::is_same<etl::type_list<>, traits::argument_types>::value));
|
||||
|
||||
CHECK_FALSE(traits::is_function);
|
||||
CHECK_TRUE(traits::is_member_function);
|
||||
CHECK_FALSE(traits::is_functor);
|
||||
CHECK_FALSE(traits::is_const);
|
||||
CHECK_TRUE(traits::is_volatile);
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
CHECK_TRUE(traits::is_noexcept);
|
||||
#else
|
||||
CHECK_FALSE(traits::is_noexcept);
|
||||
#endif
|
||||
CHECK_EQUAL(0, traits::arity);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_member_function_void_const_volatile_noexcept)
|
||||
{
|
||||
using traits = etl::function_traits<decltype(&Object::member_void_const_volatile_noexcept)>;
|
||||
|
||||
CHECK_TRUE((std::is_same<void(void), traits::function_type>::value));
|
||||
CHECK_TRUE((std::is_same<void, traits::return_type>::value));
|
||||
CHECK_TRUE((std::is_same<Object, traits::object_type>::value));
|
||||
CHECK_TRUE((std::is_same<etl::type_list<>, traits::argument_types>::value));
|
||||
|
||||
CHECK_FALSE(traits::is_function);
|
||||
CHECK_TRUE(traits::is_member_function);
|
||||
CHECK_FALSE(traits::is_functor);
|
||||
CHECK_TRUE(traits::is_const);
|
||||
CHECK_TRUE(traits::is_volatile);
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
CHECK_TRUE(traits::is_noexcept);
|
||||
#else
|
||||
CHECK_FALSE(traits::is_noexcept);
|
||||
#endif
|
||||
CHECK_EQUAL(0, traits::arity);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -172,8 +374,11 @@ namespace
|
||||
|
||||
CHECK_FALSE(traits::is_function);
|
||||
CHECK_TRUE(traits::is_member_function);
|
||||
CHECK_FALSE(traits::is_functor);
|
||||
CHECK_FALSE(traits::is_const);
|
||||
CHECK_EQUAL(2, traits::argument_count);
|
||||
CHECK_FALSE(traits::is_volatile);
|
||||
CHECK_FALSE(traits::is_noexcept);
|
||||
CHECK_EQUAL(2, traits::arity);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -188,8 +393,11 @@ namespace
|
||||
|
||||
CHECK_FALSE(traits::is_function);
|
||||
CHECK_TRUE(traits::is_member_function);
|
||||
CHECK_FALSE(traits::is_functor);
|
||||
CHECK_TRUE(traits::is_const);
|
||||
CHECK_EQUAL(2, traits::argument_count);
|
||||
CHECK_FALSE(traits::is_volatile);
|
||||
CHECK_FALSE(traits::is_noexcept);
|
||||
CHECK_EQUAL(2, traits::arity);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
@ -204,8 +412,123 @@ namespace
|
||||
|
||||
CHECK_TRUE(traits::is_function);
|
||||
CHECK_FALSE(traits::is_member_function);
|
||||
CHECK_FALSE(traits::is_functor);
|
||||
CHECK_FALSE(traits::is_const);
|
||||
CHECK_EQUAL(1, traits::argument_count);
|
||||
CHECK_FALSE(traits::is_volatile);
|
||||
CHECK_FALSE(traits::is_noexcept);
|
||||
CHECK_EQUAL(1, traits::arity);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_lambda)
|
||||
{
|
||||
auto lambda = [](int a, const std::string& s) -> long { return static_cast<long>(a + s.size()); };
|
||||
|
||||
using traits = etl::function_traits<decltype(lambda)>;
|
||||
|
||||
CHECK_TRUE((std::is_same<long(int, const std::string&), traits::function_type>::value));
|
||||
CHECK_TRUE((std::is_same<long, traits::return_type>::value));
|
||||
CHECK_TRUE((std::is_same<decltype(lambda), traits::object_type>::value));
|
||||
CHECK_TRUE((std::is_same<etl::type_list<int, const std::string&>, traits::argument_types>::value));
|
||||
|
||||
CHECK_FALSE(traits::is_function);
|
||||
CHECK_TRUE(traits::is_member_function);
|
||||
CHECK_TRUE(traits::is_functor);
|
||||
CHECK_TRUE(traits::is_const);
|
||||
CHECK_FALSE(traits::is_volatile);
|
||||
CHECK_FALSE(traits::is_noexcept);
|
||||
CHECK_EQUAL(2, traits::arity);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_functor)
|
||||
{
|
||||
struct functor
|
||||
{
|
||||
long operator()(int a, const std::string& s)
|
||||
{
|
||||
return static_cast<long>(a + s.size());
|
||||
};
|
||||
};
|
||||
|
||||
using traits = etl::function_traits<functor>;
|
||||
|
||||
CHECK_TRUE((std::is_same<long(int, const std::string&), traits::function_type>::value));
|
||||
CHECK_TRUE((std::is_same<long, traits::return_type>::value));
|
||||
CHECK_TRUE((std::is_same<functor, traits::object_type>::value));
|
||||
CHECK_TRUE((std::is_same<etl::type_list<int, const std::string&>, traits::argument_types>::value));
|
||||
|
||||
CHECK_FALSE(traits::is_function);
|
||||
CHECK_TRUE(traits::is_member_function);
|
||||
CHECK_TRUE(traits::is_functor);
|
||||
CHECK_FALSE(traits::is_const);
|
||||
CHECK_FALSE(traits::is_volatile);
|
||||
CHECK_FALSE(traits::is_noexcept);
|
||||
CHECK_EQUAL(2, traits::arity);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Forwarding of top-level cv/ref on the whole type to the unqualified type
|
||||
TEST(test_function_traits_forward_cvref_free_ptr)
|
||||
{
|
||||
using ptr_t = decltype(&free_void);
|
||||
using const_ptr_t = typename std::add_const<ptr_t>::type; // void(* const)()
|
||||
using ref_ptr_t = ptr_t&; // void(*&)()
|
||||
|
||||
using traits_c = etl::function_traits<const_ptr_t>;
|
||||
using traits_r = etl::function_traits<ref_ptr_t>;
|
||||
|
||||
CHECK_TRUE((std::is_same<void(void), traits_c::function_type>::value));
|
||||
CHECK_TRUE((std::is_same<void(void), traits_r::function_type>::value));
|
||||
CHECK_TRUE(traits_c::is_function);
|
||||
CHECK_TRUE(traits_r::is_function);
|
||||
CHECK_FALSE(traits_c::is_member_function);
|
||||
CHECK_FALSE(traits_r::is_member_function);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_function_traits_forward_cvref_member_ptr)
|
||||
{
|
||||
using mptr_t = decltype(&Object::member_int);
|
||||
using const_mptr_t = typename std::add_const<mptr_t>::type; // int (Object::* const)(int,int)
|
||||
using ref_mptr_t = mptr_t&; // int (Object::*&)(int,int)
|
||||
|
||||
using traits_c = etl::function_traits<const_mptr_t>;
|
||||
using traits_r = etl::function_traits<ref_mptr_t>;
|
||||
|
||||
CHECK_TRUE((std::is_same<int(int, int), traits_c::function_type>::value));
|
||||
CHECK_TRUE((std::is_same<int(int, int), traits_r::function_type>::value));
|
||||
CHECK_FALSE(traits_c::is_function);
|
||||
CHECK_FALSE(traits_r::is_function);
|
||||
CHECK_TRUE(traits_c::is_member_function);
|
||||
CHECK_TRUE(traits_r::is_member_function);
|
||||
CHECK_TRUE((std::is_same<Object, traits_c::object_type>::value));
|
||||
CHECK_TRUE((std::is_same<Object, traits_r::object_type>::value));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Ensure function_traits resolves for Functor and const Functor
|
||||
TEST(test_function_traits_functor_and_const_functor)
|
||||
{
|
||||
using traits_f = etl::function_traits<Functor>;
|
||||
using traits_cf = etl::function_traits<FunctorConst>;
|
||||
|
||||
// Both should be recognized as functor types
|
||||
CHECK_TRUE(traits_f::is_functor);
|
||||
CHECK_TRUE(traits_cf::is_functor);
|
||||
|
||||
// The function_type should be int(int)
|
||||
CHECK_TRUE((std::is_same<int(int), traits_f::function_type>::value));
|
||||
CHECK_TRUE((std::is_same<int(int), traits_cf::function_type>::value));
|
||||
|
||||
// const Functor should be marked const
|
||||
CHECK_FALSE(traits_f::is_const);
|
||||
CHECK_TRUE(traits_cf::is_const);
|
||||
|
||||
CHECK_TRUE((std::is_same<Functor, traits_f::object_type>::value));
|
||||
CHECK_TRUE((std::is_same<FunctorConst, traits_cf::object_type>::value));
|
||||
CHECK_EQUAL(1, traits_f::arity);
|
||||
CHECK_EQUAL(1, traits_cf::arity);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -140,6 +140,67 @@ namespace
|
||||
struct other_specialized
|
||||
{
|
||||
};
|
||||
|
||||
struct MF
|
||||
{
|
||||
int f(int) { return 0; }
|
||||
int fc(int) const { return 0; }
|
||||
int fv(int) volatile { return 0; }
|
||||
int fcv(int) const volatile { return 0; }
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
int fl(int) & { return 0; }
|
||||
int flc(int) const & { return 0; }
|
||||
int flv(int) volatile & { return 0; }
|
||||
int flcv(int) const volatile & { return 0; }
|
||||
|
||||
int fr(int) && { return 0; }
|
||||
int frc(int) const && { return 0; }
|
||||
int frv(int) volatile && { return 0; }
|
||||
int frcv(int) const volatile && { return 0; }
|
||||
#endif
|
||||
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
int fn(int) noexcept { return 0; }
|
||||
int fnc(int) const noexcept { return 0; }
|
||||
int fnv(int) volatile noexcept { return 0; }
|
||||
int fncv(int) const volatile noexcept { return 0; }
|
||||
|
||||
int fnl(int) & noexcept { return 0; }
|
||||
int fnlc(int) const & noexcept { return 0; }
|
||||
int fnlv(int) volatile & noexcept { return 0; }
|
||||
int fnlcv(int) const volatile & noexcept { return 0; }
|
||||
|
||||
int fnr(int) && noexcept { return 0; }
|
||||
int fnrc(int) const && noexcept { return 0; }
|
||||
int fnrv(int) volatile && noexcept { return 0; }
|
||||
int fnrcv(int) const volatile && noexcept { return 0; }
|
||||
#endif
|
||||
|
||||
int fvar(int, ...) { return 0; }
|
||||
int fvarc(int, ...) const { return 0; }
|
||||
};
|
||||
|
||||
struct MO
|
||||
{
|
||||
int data;
|
||||
};
|
||||
|
||||
static int f(int) { return 0; }
|
||||
static int fvar(...) { return 0; }
|
||||
static int fvar2(int, ...) { return 0; }
|
||||
|
||||
template <typename T, typename... TArgs>
|
||||
static T ft(TArgs...) { return T(); }
|
||||
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
static int fn(int) noexcept { return 0; }
|
||||
static int fnvar(...) noexcept { return 0; }
|
||||
static int fnvar2(int, ...) noexcept { return 0; }
|
||||
|
||||
template <typename T, typename... TArgs>
|
||||
static T fnt(TArgs...) noexcept { return T(); }
|
||||
#endif
|
||||
}
|
||||
|
||||
// Definitions for when the STL and compiler built-ins are not available.
|
||||
@ -1490,4 +1551,118 @@ namespace
|
||||
CHECK_FALSE(c1);
|
||||
}
|
||||
#endif
|
||||
|
||||
//*************************************************************************
|
||||
// Basic cv for member function pointers
|
||||
TEST(test_is_member_function_pointer)
|
||||
{
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::f)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fc)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fv)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fcv)>::value));
|
||||
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fl)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::flc)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::flv)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::flcv)>::value));
|
||||
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fr)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::frc)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::frv)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::frcv)>::value));
|
||||
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fn)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fnc)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fnv)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fncv)>::value));
|
||||
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fnl)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fnlc)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fnlv)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fnlcv)>::value));
|
||||
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fnr)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fnrc)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fnrv)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fnrcv)>::value));
|
||||
#endif
|
||||
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fvar)>::value));
|
||||
CHECK_TRUE((etl::is_member_function_pointer<decltype(&MF::fvarc)>::value));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Negative tests for member function pointer trait
|
||||
TEST(test_is_member_function_pointer_negative)
|
||||
{
|
||||
(void)f(0);
|
||||
|
||||
// Free function pointer
|
||||
CHECK_FALSE((etl::is_member_function_pointer<decltype(&f)>::value));
|
||||
|
||||
// Member object pointer
|
||||
CHECK_FALSE((etl::is_member_function_pointer<int MF::*>::value));
|
||||
|
||||
// Plain function type (not pointer)
|
||||
CHECK_FALSE((etl::is_member_function_pointer<int(int)>::value));
|
||||
|
||||
// Non-function type
|
||||
CHECK_FALSE((etl::is_member_function_pointer<int>::value));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Member object pointer trait
|
||||
TEST(test_is_member_object_pointer)
|
||||
{
|
||||
CHECK_TRUE((etl::is_member_object_pointer<int MO::*>::value));
|
||||
|
||||
// Not a member object pointer
|
||||
CHECK_FALSE((etl::is_member_object_pointer<int (MF::*)(int)>::value));
|
||||
CHECK_FALSE((etl::is_member_object_pointer<int*>::value));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Member pointer (either member object or member function pointer)
|
||||
TEST(test_is_member_pointer_any)
|
||||
{
|
||||
CHECK_TRUE((etl::is_member_pointer<int MF::*>::value));
|
||||
CHECK_TRUE((etl::is_member_pointer<int (MF::*)(int)>::value));
|
||||
|
||||
// Not member pointers
|
||||
CHECK_FALSE((etl::is_member_pointer<int*>::value));
|
||||
CHECK_FALSE((etl::is_member_pointer<decltype(f)>::value));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// Function type detection
|
||||
TEST(test_is_function)
|
||||
{
|
||||
(void)f(0);
|
||||
(void)fvar();
|
||||
(void)fvar2(0);
|
||||
(void)ft<int, int, double>(0, 0.0);
|
||||
|
||||
CHECK_TRUE((etl::is_function<decltype(f)>::value));
|
||||
CHECK_TRUE((etl::is_function<decltype(fvar)>::value));
|
||||
CHECK_TRUE((etl::is_function<decltype(fvar2)>::value));
|
||||
CHECK_TRUE((etl::is_function<decltype(ft<int, int, double>)>::value));
|
||||
|
||||
#if ETL_HAS_NOEXCEPT_FUNCTION_TYPE
|
||||
(void)fn(0);
|
||||
(void)fnvar();
|
||||
(void)fnvar2(0);
|
||||
(void)fnt<int, int, double>(0, 0.0);
|
||||
|
||||
CHECK_TRUE((etl::is_function<decltype(fn)>::value));
|
||||
CHECK_TRUE((etl::is_function<decltype(fnvar)>::value));
|
||||
CHECK_TRUE((etl::is_function<decltype(fnvar2)>::value));
|
||||
CHECK_TRUE((etl::is_function<decltype(fnt<int, int, double>)>::value));
|
||||
#endif
|
||||
|
||||
CHECK_FALSE((etl::is_function<int>::value));
|
||||
CHECK_FALSE((etl::is_function<int*>::value));
|
||||
CHECK_FALSE((etl::is_function<int MF::*>::value));
|
||||
CHECK_FALSE((etl::is_function<int (MF::*)(int)>::value)); // pointer, not function
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user