Skip to content

Commit

Permalink
[SymForce] Fix function_traits for (*const&) function pointers
Browse files Browse the repository at this point in the history
Topic: sf-constref-fp
GitOrigin-RevId: a1ede3c8b4f411652f86c8f896384bb98df9e4e1
  • Loading branch information
aaron-skydio committed Aug 22, 2023
1 parent e2e1113 commit 4adde6d
Showing 1 changed file with 30 additions and 11 deletions.
41 changes: 30 additions & 11 deletions symforce/opt/templates.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,7 @@
namespace sym {

// ------------------------------------------------------------------------------------------------
// Function traits
//
// Extracts the number of arguments and types of the arguments and return value.
// Handle generic functors by looking at the 'operator()'.
// ------------------------------------------------------------------------------------------------

// C++14 implementation of remove_cvref
template <class T>
struct remove_cvref {
using type = std::remove_cv_t<std::remove_reference_t<T>>;
Expand All @@ -24,8 +19,19 @@ struct remove_cvref {
template <typename T>
using remove_cvref_t = typename remove_cvref<T>::type;

// ------------------------------------------------------------------------------------------------
// Function traits
//
// Extracts the number of arguments and types of the arguments and return value.
// Handles:
// - Function pointers
// - Member function pointers
// - Functors (objects with operator())
// - Lambdas
// ------------------------------------------------------------------------------------------------

template <typename T>
struct function_traits : public function_traits<decltype(&remove_cvref_t<T>::operator())> {};
struct function_traits;

// Traits implementation
template <typename ReturnType, typename... Args>
Expand All @@ -44,12 +50,20 @@ struct function_traits<ReturnType(Args...)> {
};
};

// Specialize for function pointers
template <typename ReturnType, typename... Args>
struct function_traits<ReturnType (&)(Args...)> : public function_traits<ReturnType(Args...)> {};
constexpr std::size_t function_traits<ReturnType(Args...)>::num_arguments;

template <typename ReturnType, typename... Args>
struct function_traits<ReturnType (*)(Args...)> : public function_traits<ReturnType(Args...)> {};
// Specializations to remove type modifiers
template <typename T>
struct function_traits<T*> : public function_traits<T> {};
template <typename T>
struct function_traits<T&> : public function_traits<T> {};
template <typename T>
struct function_traits<T&&> : public function_traits<T> {};
template <typename T>
struct function_traits<const T> : public function_traits<T> {};
template <typename T>
struct function_traits<volatile T> : public function_traits<T> {};

// Specialize for member function pointers
template <typename ClassType, typename ReturnType, typename... Args>
Expand All @@ -61,4 +75,9 @@ template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType (ClassType::*)(Args...) const>
: public function_traits<ReturnType(Args...)> {};

// ------------------------------------------------------------------------------------------------
// Specialize for functors
template <typename T>
struct function_traits : public function_traits<decltype(&T::operator())> {};

} // namespace sym

0 comments on commit 4adde6d

Please sign in to comment.