7 #ifndef PXR_BASE_TF_DIAGNOSTIC_CONTAINER_H
8 #define PXR_BASE_TF_DIAGNOSTIC_CONTAINER_H
22 #include <type_traits>
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>();
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; }
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');
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<
165 using _WarnResult =
typename _SafeInvokeResult<
167 using _StatResult =
typename _SafeInvokeResult<
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;
197 #endif // PXR_BASE_TF_DIAGNOSTIC_CONTAINER_H
typename std::conditional< B, T, F >::type conditional_t
#define PXR_NAMESPACE_OPEN_SCOPE
std::vector< TfWarning > const & GetWarnings() const
std::vector< TfStatus > const & GetStatuses() const
GLint GLint GLsizei GLint GLenum GLenum type
Iterator GetIterator() const
std::vector< TfError > const & GetErrors() const
void Append(TfStatus const &s)
#define PXR_NAMESPACE_CLOSE_SCOPE
GLubyte GLubyte GLubyte GLubyte w
void Append(TfError const &e)
Iterator(Tf_DiagnosticContainer const &container)
void Append(TfWarning const &w)