Loading...
Searching...
No Matches
meta.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_META_H
9#define PXR_BASE_TF_META_H
10
11#include "pxr/pxr.h"
12
13#include <cstddef>
14#include <tuple>
15#include <type_traits>
16
17// Some small metaprogramming utilities.
18
19PXR_NAMESPACE_OPEN_SCOPE
20
21// Simple compile-time type list.
22template <class... Args> struct TfMetaList {};
23
24// Helper for TfMetaApply.
25template<template <class...> class Cls, class List>
26struct Tf_MetaApplyImpl;
27
28template<template <class...> class Cls, class... Args>
29struct Tf_MetaApplyImpl<Cls, TfMetaList<Args...>>
30{
31 using Type = Cls<Args...>;
32};
33
34// Apply \p TypeList<Args...> to class template \p Cls, producing Cls<Args...>
35template <template <class...> class Cls, class TypeList>
36using TfMetaApply = typename Tf_MetaApplyImpl<Cls, TypeList>::Type;
37
38// TfMetaHead<A1, A2, ... An> -> A1
39template <class Head, class...>
40using TfMetaHead = Head;
41
42// TfMetaTail<A1, A2, ... An> -> TfMetaList<A2, ... An>.
43template <class Head, class... Tail>
44using TfMetaTail = TfMetaList<Tail...>;
45
46template <class L1, class L2>
47struct Tf_MetaConcatImpl;
48
49template <class... A1s, class... A2s>
50struct Tf_MetaConcatImpl<TfMetaList<A1s...>, TfMetaList<A2s...>>
51{
52 using Type = TfMetaList<A1s..., A2s...>;
53};
54
55// TfMetaConcat<TfMetaList<Xs...>, TfMetaList<Ys...>>
56// -> TfMetaList<Xs..., Ys...>
57template <class L1, class L2>
58using TfMetaConcat = typename Tf_MetaConcatImpl<L1, L2>::Type;
59
60// TfMetaDecay<A1, A2, ... An>
61// -> TfMetaList<std::decay_t<A1>, ... std::decay_t<An>>
62template <class... Ts>
63using TfMetaDecay = TfMetaList<std::decay_t<Ts>...>;
64
65// TfMetaLength produces an integral_constant<size_t, N> where N is the number
66// of \p Xs.
67template <class... Xs>
68using TfMetaLength = std::integral_constant<size_t, sizeof...(Xs)>;
69
70// Lighter-weight compile-time conditional type selection implementation.
71template <bool Condition>
72struct Tf_ConditionalImpl {
73 template <class T, class>
74 using Type = T;
75};
76
77template <>
78struct Tf_ConditionalImpl<false> {
79 template <class, class F>
80 using Type = F;
81};
82
83// This is a bit lighter weight at compile time than std::conditional because it
84// instantiates a separate template for the condition from the selector.
85template <bool Cond, class T, class F>
86using TfConditionalType =
87 typename Tf_ConditionalImpl<Cond>::template Type<T, F>;
88
89PXR_NAMESPACE_CLOSE_SCOPE
90
91#endif // PXR_BASE_TF_META_H