HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
valueComposeOver.h
Go to the documentation of this file.
1 //
2 // Copyright 2025 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_VT_VALUE_COMPOSE_OVER_H
9 #define PXR_BASE_VT_VALUE_COMPOSE_OVER_H
10 
11 #include "pxr/pxr.h"
12 
13 #include "pxr/base/vt/api.h"
14 #include "pxr/base/vt/traits.h"
15 #include "pxr/base/vt/types.h"
16 #include "pxr/base/vt/value.h"
17 #include "pxr/base/vt/valueRef.h"
18 
19 #include <optional>
20 
22 
23 /// Return true if the result of `VtValueCanComposeOver(val, x)` could be true
24 /// for some \p x, false otherwise. The empty value can always compose-over.
25 /// This is a faster check than the two-argument form of
26 /// `VtValueCanComposeOver()`.
27 inline bool
29  return val.CanComposeOver();
30 }
31 
32 /// Return true if VtRegisterComposeOver() has been called with \p strongType as
33 /// the stronger type.
34 VT_API bool
35 VtValueTypeCanComposeOver(std::type_info const &strongType);
36 
37 /// Return true if `stronger` composes non-trivially over `weaker`.
38 /// Specifically, if `stronger` can never compose-over (see the single-argument
39 /// form) or if no compose-over functionality has been defined for values of
40 /// `stronger`'s type over values of `weaker`'s type, return false. Otherwise
41 /// return true. In other words, if this function returns false, then
42 /// `VtValueComposeOver(stronger, weaker)` always returns `stronger`.
43 VT_API bool
45 
46 /// If `VtValueCanComposeOver(stronger, weaker)`, then return
47 /// `VtValueComposeOver(stronger, weaker)`. Otherwise return an empty optional.
48 VT_API std::optional<VtValue>
50 
51 /// Return the result of composing `stronger` over `weaker`. If `stronger`
52 /// never composes-over, or if no compose-over functionality has been defined
53 /// for values of `stronger`'s type over `weaker`'s type, return `stronger`.
54 /// Otherwise invoke the compose-over function and return the result. If
55 /// `stronger` is empty, return `weaker`.
57 VtValueComposeOver(VtValueRef stronger, VtValueRef weaker);
58 
59 /// A special sentinel type and singular value that can be used to "finalize" a
60 /// composing type. For example, `VtArrayEdit<T>` can compose over
61 /// `VtBackground`. It does so by applying its edits to an empty `VtArray<T>`
62 /// to produce a final array. Using a single-typed sentinel lets type-agnostic
63 /// code "finalize" composing values uniformly. The name "background" is by
64 /// analogy to image compositing.
65 struct VtBackgroundType {};
66 inline constexpr VtBackgroundType VtBackground;
67 
68 // Required to store VtBackground in a VtValue.
69 inline bool
71  return true;
72 }
73 
74 // Private helper implementation.
75 VT_API void
76 Vt_RegisterComposeOver(std::type_info const &strongType,
77  std::type_info const &weakType,
78  void (*voidFn)(),
79  VtValue (*over)(VtValueRef, VtValueRef, void (*)()));
80 
81 /// Register compose-over functionality for values of type `Strong` over `Weak`.
82 /// It is essential that the function be associative. That is, ((`A` over `B`)
83 /// over `C`) must yield the same result as (`A` over (`B` over `C`)).
84 template <class Ret, class Strong, class Weak>
85 void
86 VtRegisterComposeOver(Ret (*fn)(Strong const &, Weak const &))
87 {
88  static_assert(!VtIsKnownValueType<Strong>() || VtIsArrayEdit<Strong>::value,
89  "Unexpected compose-over registration for one of the "
90  "known value types");
91 
93  "Use VT_VALUE_TYPE_CAN_COMPOSE or specialize "
94  "VtValueTypeCanCompose<> before registering compose-over "
95  "functionality");
96 
97  using TypedFn = Ret (*)(Strong const &, Weak const &);
98  using VoidFn = void (*)();
99 
100  VoidFn voidFn = reinterpret_cast<VoidFn>(fn);
102  typeid(Strong), typeid(Weak), voidFn,
103  [](VtValueRef strong, VtValueRef weak, void (*vFn)()) {
104  TypedFn tFn = reinterpret_cast<TypedFn>(vFn);
105  TF_DEV_AXIOM(strong.IsHolding<Strong>());
106  TF_DEV_AXIOM(weak.IsHolding<Weak>());
107  return VtValue {
108  tFn(strong.UncheckedGet<Strong>(), weak.UncheckedGet<Weak>())
109  };
110  });
111 }
112 
114 
115 #endif // PXR_BASE_VT_VALUE_COMPOSE_OVER_H
void
Definition: png.h:1083
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
PXR_NAMESPACE_OPEN_SCOPE bool VtValueCanComposeOver(VtValueRef val)
VT_API std::optional< VtValue > VtValueTryComposeOver(VtValueRef stronger, VtValueRef weaker)
#define VT_API
Definition: api.h:23
void VtRegisterComposeOver(Ret(*fn)(Strong const &, Weak const &))
bool IsHolding() const
Definition: valueRef.h:403
VT_API bool VtValueTypeCanComposeOver(std::type_info const &strongType)
#define TF_DEV_AXIOM(cond)
bool CanComposeOver() const
Definition: valueRef.h:535
ImageBuf OIIO_API over(const ImageBuf &A, const ImageBuf &B, ROI roi={}, int nthreads=0)
constexpr VtBackgroundType VtBackground
_TypeInfoFor< T >::GetObjResultType UncheckedGet() const
Definition: valueRef.h:452
GLuint GLfloat * val
Definition: glcorearb.h:1608
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
VT_API void Vt_RegisterComposeOver(std::type_info const &strongType, std::type_info const &weakType, void(*voidFn)(), VtValue(*over)(VtValueRef, VtValueRef, void(*)()))
VT_API VtValue VtValueComposeOver(VtValueRef stronger, VtValueRef weaker)
Definition: value.h:89
bool operator==(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Equality operator, does exact floating point comparisons.
Definition: Mat3.h:542
A trait to detect instantiations of VtArrayEdit, specialized in arrayEdit.h.
Definition: traits.h:26