Loading...
Searching...
No Matches
functionTraits.h
1//
2// Copyright 2023 Pixar
3//
4// Licensed under the Apache License, Version 2.0 (the "Apache License")
5// with the following modification; you may not use this file except in
6// compliance with the Apache License and the following modification to it:
7// Section 6. Trademarks. is deleted and replaced with:
8//
9// 6. Trademarks. This License does not grant permission to use the trade
10// names, trademarks, service marks, or product names of the Licensor
11// and its affiliates, except as required to comply with Section 4(c) of
12// the License and to reproduce the content of the NOTICE file.
13//
14// You may obtain a copy of the Apache License at
15//
16// http://www.apache.org/licenses/LICENSE-2.0
17//
18// Unless required by applicable law or agreed to in writing, software
19// distributed under the Apache License with the above modification is
20// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21// KIND, either express or implied. See the Apache License for the specific
22// language governing permissions and limitations under the Apache License.
23//
24
25#ifndef PXR_BASE_TF_FUNCTION_TRAITS_H
26#define PXR_BASE_TF_FUNCTION_TRAITS_H
27
28#include "pxr/pxr.h"
29
30#include "pxr/base/tf/meta.h"
31
32#include <cstddef>
33#include <tuple>
34#include <type_traits>
35
36PXR_NAMESPACE_OPEN_SCOPE
37
38// Function signature representation.
39template <class Ret, class ArgTypeList>
40struct Tf_FuncSig
41{
42 using ReturnType = Ret;
43 using ArgTypes = ArgTypeList;
44 using ArgsTuple = TfMetaApply<std::tuple, ArgTypes>;
45 static const size_t Arity = TfMetaApply<TfMetaLength, ArgTypes>::value;
46
47 template <size_t N>
48 using NthArg = std::tuple_element_t<N, ArgsTuple>;
49};
50
51// Produce a new Tf_FuncSig from FuncSig by removing the initial "this"
52// argument.
53template <class FuncSig>
54using Tf_RemoveThisArg = Tf_FuncSig<
55 typename FuncSig::ReturnType,
56 TfMetaApply<TfMetaTail, typename FuncSig::ArgTypes>>;
57
58// For callable function objects, get signature from operator(), but remove the
59// 'this' arg from that.
60template <class Fn>
61struct Tf_GetFuncSig
62{
63 using Type = Tf_RemoveThisArg<
64 typename Tf_GetFuncSig<
65 decltype(&std::remove_reference<Fn>::type::operator())
66 >::Type
67 >;
68};
69
70// Member function pointers, with optional 'const' and ref-qualifiers.
71template <class Ret, class Cls, class... Args>
72struct Tf_GetFuncSig<Ret (Cls::*)(Args...)>
73{
74 using Type = Tf_FuncSig<Ret, TfMetaList<Cls &, Args...>>;
75};
76template <class Ret, class Cls, class... Args>
77struct Tf_GetFuncSig<Ret (Cls::*)(Args...) &>
78{
79 using Type = Tf_FuncSig<Ret, TfMetaList<Cls &, Args...>>;
80};
81template <class Ret, class Cls, class... Args>
82struct Tf_GetFuncSig<Ret (Cls::*)(Args...) &&>
83{
84 using Type = Tf_FuncSig<Ret, TfMetaList<Cls &&, Args...>>;
85};
86
87template <class Ret, class Cls, class... Args>
88struct Tf_GetFuncSig<Ret (Cls::*)(Args...) const>
89{
90 using Type = Tf_FuncSig<Ret, TfMetaList<Cls const &, Args...>>;
91};
92template <class Ret, class Cls, class... Args>
93struct Tf_GetFuncSig<Ret (Cls::*)(Args...) const &>
94{
95 using Type = Tf_FuncSig<Ret, TfMetaList<Cls const &, Args...>>;
96};
97template <class Ret, class Cls, class... Args>
98struct Tf_GetFuncSig<Ret (Cls::*)(Args...) const &&>
99{
100 using Type = Tf_FuncSig<Ret, TfMetaList<Cls const &&, Args...>>;
101};
102
103// Regular function pointers.
104template <class Ret, class... Args>
105struct Tf_GetFuncSig<Ret (*)(Args...)>
106{
107 using Type = Tf_FuncSig<Ret, TfMetaList<Args...>>;
108};
109
110// Function traits.
111template <class Fn>
112using TfFunctionTraits = typename Tf_GetFuncSig<Fn>::Type;
113
114PXR_NAMESPACE_CLOSE_SCOPE
115
116#endif // PXR_BASE_TF_FUNCTION_TRAITS_H
117