blob: bbcc80a4b43b31088c1eb0ae4fdeb585f13d65bb [file]
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef IREE_BASE_API_UTIL_H_
#define IREE_BASE_API_UTIL_H_
#include "absl/base/macros.h"
#include "absl/container/inlined_vector.h"
#include "absl/time/time.h"
#include "iree/base/api.h"
#include "iree/base/logging.h"
#include "iree/base/shape.h"
#include "iree/base/status.h"
namespace iree {
inline iree_status_t ToApiStatus(const Status& status) {
if (!status.ok()) {
LOG(ERROR) << status;
}
return iree_make_status(status.code());
}
inline Status FromApiStatus(iree_status_t status_code, SourceLocation loc) {
return StatusBuilder(static_cast<StatusCode>(status_code), loc);
}
#define IREE_RETURN_IF_NULL(value) \
if (!(value)) \
return ::iree::InvalidArgumentErrorBuilder(IREE_LOC) \
<< #value << " is null/empty";
// Internal helper for concatenating macro values.
#define IREE_API_STATUS_MACROS_IMPL_CONCAT_INNER_(x, y) x##y
#define IREE_API_STATUS_MACROS_IMPL_CONCAT_(x, y) \
IREE_API_STATUS_MACROS_IMPL_CONCAT_INNER_(x, y)
namespace status_macro_internal {
class StatusAdaptorForApiMacros {
public:
StatusAdaptorForApiMacros(const Status& status) : status_(status) {}
StatusAdaptorForApiMacros(Status&& status) : status_(std::move(status)) {}
StatusAdaptorForApiMacros(const StatusAdaptorForApiMacros&) = delete;
StatusAdaptorForApiMacros& operator=(const StatusAdaptorForApiMacros&) =
delete;
explicit operator bool() const { return ABSL_PREDICT_TRUE(status_.ok()); }
Status&& Consume() { return std::move(status_); }
private:
Status status_;
};
} // namespace status_macro_internal
// clang-format off
#define IREE_API_STATUS_MACROS_IMPL_ELSE_BLOCKER_ switch (0) case 0: default: // NOLINT
// clang-format on
#define IREE_API_RETURN_IF_ERROR(expr) \
IREE_API_STATUS_MACROS_IMPL_ELSE_BLOCKER_ \
if (::iree::status_macro_internal::StatusAdaptorForApiMacros \
status_adaptor = {expr}) { \
} else /* NOLINT */ \
return ::iree::ToApiStatus(status_adaptor.Consume())
#define IREE_API_ASSIGN_OR_RETURN(...) \
IREE_API_STATUS_MACROS_IMPL_GET_VARIADIC_( \
(__VA_ARGS__, IREE_API_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_3_, \
IREE_API_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_2_)) \
(__VA_ARGS__)
#define IREE_API_STATUS_MACROS_IMPL_GET_VARIADIC_HELPER_(_1, _2, _3, NAME, \
...) \
NAME
#define IREE_API_STATUS_MACROS_IMPL_GET_VARIADIC_(args) \
IREE_API_STATUS_MACROS_IMPL_GET_VARIADIC_HELPER_ args
#define IREE_API_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_2_(lhs, rexpr) \
IREE_API_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_3_(lhs, rexpr, std::move(_))
#define IREE_API_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_3_(lhs, rexpr, \
error_expression) \
IREE_API_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_( \
IREE_API_STATUS_MACROS_IMPL_CONCAT_(_status_or_value, __LINE__), lhs, \
rexpr, error_expression)
#define IREE_API_STATUS_MACROS_IMPL_ASSIGN_OR_RETURN_(statusor, lhs, rexpr, \
error_expression) \
auto statusor = (rexpr); \
if (ABSL_PREDICT_FALSE(!statusor.ok())) { \
return ::iree::ToApiStatus(std::move(statusor).status()); \
} \
lhs = std::move(statusor).ValueOrDie()
// Converts an iree_time_t to its equivalent absl::Time.
inline absl::Time ToAbslTime(iree_time_t time) {
if (time == IREE_TIME_INFINITE_PAST) {
return absl::InfinitePast();
} else if (time == IREE_TIME_INFINITE_FUTURE) {
return absl::InfiniteFuture();
} else {
return absl::FromUnixNanos(time);
}
}
// Returns a vector initialized with the contents of a C-style list query.
// For functions of the form (..., capacity, out_values, out_count) this will
// try to fetch the items and resize as needed such that the returned value
// contains all items available.
//
// Returns the empty vector if the query fails for any reason.
template <typename T, typename... Args>
absl::InlinedVector<T, 4> QueryListValues(
iree_status_t (*fn)(Args..., iree_host_size_t, T*, iree_host_size_t*),
Args... args) {
absl::InlinedVector<T, 4> values(4);
iree_host_size_t count = 0;
iree_status_t status = fn(args..., values.size(), values.data(), &count);
if (iree_status_is_out_of_range(status)) {
values.resize(count);
status = fn(args..., values.size(), values.data(), &count);
} else if (!iree_status_is_ok(status)) {
return {};
}
values.resize(count);
return values;
}
} // namespace iree
#endif // IREE_BASE_API_UTIL_H_