All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
functionTraits.h
1//
2// Copyright 2023 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7
8#ifndef PXR_BASE_TF_FUNCTION_TRAITS_H
9#define PXR_BASE_TF_FUNCTION_TRAITS_H
10
11#include "pxr/pxr.h"
12
13#include "pxr/base/tf/meta.h"
14
15#include <cstddef>
16#include <tuple>
17#include <type_traits>
18
19PXR_NAMESPACE_OPEN_SCOPE
20
21// Function signature representation.
22template <class Ret, class ArgTypeList>
23struct Tf_FuncSig
24{
25 using ReturnType = Ret;
26 using ArgTypes = ArgTypeList;
27 using ArgsTuple = TfMetaApply<std::tuple, ArgTypes>;
28 static const size_t Arity = TfMetaApply<TfMetaLength, ArgTypes>::value;
29
30 template <size_t N>
31 using NthArg = std::tuple_element_t<N, ArgsTuple>;
32};
33
34// Produce a new Tf_FuncSig from FuncSig by removing the initial "this"
35// argument.
36template <class FuncSig>
37using Tf_RemoveThisArg = Tf_FuncSig<
38 typename FuncSig::ReturnType,
39 TfMetaApply<TfMetaTail, typename FuncSig::ArgTypes>>;
40
41// For callable function objects, get signature from operator(), but remove the
42// 'this' arg from that.
43template <class Fn>
44struct Tf_GetFuncSig
45{
46 using Type = Tf_RemoveThisArg<
47 typename Tf_GetFuncSig<
48 decltype(&std::remove_reference<Fn>::type::operator())
49 >::Type
50 >;
51};
52
53// Member function pointers, with optional 'const' and ref-qualifiers.
54template <class Ret, class Cls, class... Args>
55struct Tf_GetFuncSig<Ret (Cls::*)(Args...)>
56{
57 using Type = Tf_FuncSig<Ret, TfMetaList<Cls &, Args...>>;
58};
59template <class Ret, class Cls, class... Args>
60struct Tf_GetFuncSig<Ret (Cls::*)(Args...) &>
61{
62 using Type = Tf_FuncSig<Ret, TfMetaList<Cls &, Args...>>;
63};
64template <class Ret, class Cls, class... Args>
65struct Tf_GetFuncSig<Ret (Cls::*)(Args...) &&>
66{
67 using Type = Tf_FuncSig<Ret, TfMetaList<Cls &&, Args...>>;
68};
69
70template <class Ret, class Cls, class... Args>
71struct Tf_GetFuncSig<Ret (Cls::*)(Args...) const>
72{
73 using Type = Tf_FuncSig<Ret, TfMetaList<Cls const &, Args...>>;
74};
75template <class Ret, class Cls, class... Args>
76struct Tf_GetFuncSig<Ret (Cls::*)(Args...) const &>
77{
78 using Type = Tf_FuncSig<Ret, TfMetaList<Cls const &, Args...>>;
79};
80template <class Ret, class Cls, class... Args>
81struct Tf_GetFuncSig<Ret (Cls::*)(Args...) const &&>
82{
83 using Type = Tf_FuncSig<Ret, TfMetaList<Cls const &&, Args...>>;
84};
85
86// Regular function pointers.
87template <class Ret, class... Args>
88struct Tf_GetFuncSig<Ret (*)(Args...)>
89{
90 using Type = Tf_FuncSig<Ret, TfMetaList<Args...>>;
91};
92
93// Function traits.
94template <class Fn>
95using TfFunctionTraits = typename Tf_GetFuncSig<Fn>::Type;
96
97PXR_NAMESPACE_CLOSE_SCOPE
98
99#endif // PXR_BASE_TF_FUNCTION_TRAITS_H
100