7#ifndef PXR_BASE_TF_DIAGNOSTIC_CONTAINER_H
8#define PXR_BASE_TF_DIAGNOSTIC_CONTAINER_H
13#include "pxr/base/tf/api.h"
15#include "pxr/base/tf/status.h"
17#include "pxr/base/tf/warning.h"
25PXR_NAMESPACE_OPEN_SCOPE
33class Tf_DiagnosticContainer
47 explicit Iterator(Tf_DiagnosticContainer
const &container)
48 : _container(container) {}
53 using RetT =
typename _IterNextReturnType<Fn>::Type;
55 while (_orderIndex < _container._order.size()) {
56 char c = _container._order[_orderIndex++];
59 if (
auto r = TfTryInvoke<RetT>(
60 fn, _container._errors[_errorIndex++])) {
65 if (
auto r = TfTryInvoke<RetT>(
66 fn, _container._warnings[_warningIndex++])) {
71 if (
auto r = TfTryInvoke<RetT>(
72 fn, _container._statuses[_statusIndex++])) {
78 return TfNotInvoked<RetT>();
82 Tf_DiagnosticContainer
const &_container;
83 size_t _orderIndex = 0;
84 size_t _errorIndex = 0;
85 size_t _warningIndex = 0;
86 size_t _statusIndex = 0;
90 bool IsEmpty()
const {
return _order.empty(); }
93 std::vector<TfError>
const& GetErrors()
const {
return _errors; }
96 std::vector<TfWarning>
const& GetWarnings()
const {
return _warnings; }
99 std::vector<TfStatus>
const& GetStatuses()
const {
return _statuses; }
103 void Append(
TfError const &e) {
104 _errors.push_back(e);
105 _order.push_back(
'E');
109 _warnings.push_back(w);
110 _order.push_back(
'W');
114 _statuses.push_back(s);
115 _order.push_back(
'S');
129 Iterator GetIterator()
const {
130 return Iterator(*
this);
140 template <
class Fn,
class Arg,
bool Invocable>
141 struct _SafeInvokeResult {
145 template <
class Fn,
class Arg>
146 struct _SafeInvokeResult<Fn, Arg, true> {
147 using type = std::invoke_result_t<Fn, Arg>;
151 struct _IterNextReturnType {
152 static constexpr bool _ErrInvocable =
153 std::is_invocable_v<Fn, TfError const &>;
154 static constexpr bool _WarnInvocable =
155 std::is_invocable_v<Fn, TfWarning const &>;
156 static constexpr bool _StatInvocable =
157 std::is_invocable_v<Fn, TfStatus const &>;
159 static_assert(_ErrInvocable || _WarnInvocable || _StatInvocable,
160 "Callable must be invocable with at least one of "
161 "TfError, TfWarning, or TfStatus");
163 using _ErrResult =
typename _SafeInvokeResult<
164 Fn,
TfError const &, _ErrInvocable>::type;
165 using _WarnResult =
typename _SafeInvokeResult<
166 Fn,
TfWarning const &, _WarnInvocable>::type;
167 using _StatResult =
typename _SafeInvokeResult<
168 Fn,
TfStatus const &, _StatInvocable>::type;
170 using Type = std::conditional_t<
171 _ErrInvocable, _ErrResult,
173 _WarnInvocable, _WarnResult, _StatResult>>;
175 static_assert(!_ErrInvocable || !_WarnInvocable ||
176 std::is_same_v<_ErrResult, _WarnResult>,
177 "Callable must return the same type for all "
178 "invocable diagnostic types");
179 static_assert(!_ErrInvocable || !_StatInvocable ||
180 std::is_same_v<_ErrResult, _StatResult>,
181 "Callable must return the same type for all "
182 "invocable diagnostic types");
183 static_assert(!_WarnInvocable || !_StatInvocable ||
184 std::is_same_v<_WarnResult, _StatResult>,
185 "Callable must return the same type for all "
186 "invocable diagnostic types");
189 std::vector<TfError> _errors;
190 std::vector<TfWarning> _warnings;
191 std::vector<TfStatus> _statuses;
195PXR_NAMESPACE_CLOSE_SCOPE
Provide facilities for error handling in script.
Represents an object that contains error information.
Represents an object that contains information about a status message.
Represents an object that contains information about a warning.