Skip to content

Commit

Permalink
Refactor and adding tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jatinchowdhury18 committed Oct 13, 2023
1 parent 8ab950a commit c458482
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 134 deletions.
135 changes: 135 additions & 0 deletions modules/common/chowdsp_core/Types/chowdsp_TypeHasCheckers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#pragma once

/**
* Creates a constexpr bool that checks if a class has the given static method.
*
* Usage:
* @code {.cpp}
* CHOWDSP_CHECK_HAS_STATIC_METHOD(HasToString, toString, std::declval<int>())
* static_assert(HasToString<MyClass>, "MyClass must have a static toString(int) method!");
* @endcode
*/
#define CHOWDSP_CHECK_HAS_STATIC_METHOD(Name, Method, ...) \
template <typename _T> \
class Test_##Name \
{ \
using No = char; \
using Yes = long; \
static_assert (sizeof (No) != sizeof (Yes), "Yes and No have the same size on this platform, undefined behaviour will ensue!"); \
\
template <typename C> \
static Yes test (decltype (C::Method (__VA_ARGS__))*); \
\
template <typename C> \
static No test (...); \
\
public: \
enum \
{ \
value = sizeof (test<_T> (nullptr)) == sizeof (Yes) \
}; \
}; \
template <typename _T> \
static constexpr bool Name = Test_##Name<_T>::value;

/**
* Creates a constexpr bool that checks if a class has the given non-static method.
*
* Usage:
* @code {.cpp}
* CHOWDSP_CHECK_HAS_METHOD(HasGetAtIndex, getAtIndex, std::declval<int>())
* static_assert(HasGetAtIndex<MyClass>, "MyClass must have getAtIndex(int) method!");
* @endcode
*/
#define CHOWDSP_CHECK_HAS_METHOD(Name, Method, ...) \
template <typename _T> \
class Test_##Name \
{ \
using No = char; \
using Yes = long; \
static_assert (sizeof (No) != sizeof (Yes), "Yes and No have the same size on this platform, undefined behaviour will ensue!"); \
\
template <typename C> \
static Yes test (decltype (std::declval<C>().Method (__VA_ARGS__))*); \
\
template <typename C> \
static No test (...); \
\
public: \
enum \
{ \
value = sizeof (test<_T> (nullptr)) == sizeof (Yes) \
}; \
}; \
template <typename _T> \
static constexpr bool Name = Test_##Name<_T>::value;

/**
* Creates a constexpr bool that checks if a class has the given static member variable.
*
* Usage:
* @code {.cpp}
* CHOWDSP_CHECK_HAS_STATIC_MEMBER(HasName, name)
* static_assert(HasName<MyClass>, "MyClass must have a static name member!");
* @endcode
*/
#define CHOWDSP_CHECK_HAS_STATIC_MEMBER(Name, Member) \
template <typename _T> \
class Test_##Name \
{ \
using No = char; \
using Yes = long; \
static_assert (sizeof (No) != sizeof (Yes), "Yes and No have the same size on this platform, undefined behaviour will ensue!"); \
\
template <typename C> \
static std::enable_if_t<std::is_member_pointer_v<decltype (&C::Member)>, No> test (decltype (C::Member)*); \
\
template <typename C> \
static std::enable_if_t<! std::is_member_pointer_v<decltype (&C::Member)>, Yes> test (decltype (C::Member)*); \
\
template <typename C> \
static No test (...); \
\
public: \
enum \
{ \
value = sizeof (test<_T> (nullptr)) == sizeof (Yes) \
}; \
}; \
template <typename _T> \
static constexpr bool Name = Test_##Name<_T>::value;

/**
* Creates a constexpr bool that checks if a class has the given non-static member variable.
*
* Usage:
* @code {.cpp}
* CHOWDSP_CHECK_HAS_MEMBER(HasName, name)
* static_assert(HasName<MyClass>, "MyClass must have `name` member variable!");
* @endcode
*/
#define CHOWDSP_CHECK_HAS_MEMBER(Name, Member) \
template <typename _T> \
class Test_##Name \
{ \
using No = char; \
using Yes = long; \
static_assert (sizeof (No) != sizeof (Yes), "Yes and No have the same size on this platform, undefined behaviour will ensue!"); \
\
template <typename C> \
static std::enable_if_t<std::is_member_pointer_v<decltype (&C::Member)>, Yes> test (decltype (std::declval<C>().Member)*); \
\
template <typename C> \
static std::enable_if_t<! std::is_member_pointer_v<decltype (&C::Member)>, No> test (decltype (std::declval<C>().Member)*); \
\
template <typename C> \
static No test (...); \
\
public: \
enum \
{ \
value = sizeof (test<_T> (nullptr)) == sizeof (Yes) \
}; \
}; \
template <typename _T> \
static constexpr bool Name = Test_##Name<_T>::value;
Loading

0 comments on commit c458482

Please sign in to comment.