Program Listing for File rets.hpp
↰ Return to documentation for file (include/client/syscalls/rets.hpp
)
/*
Copyright 2018-2024, Barcelona Supercomputing Center (BSC), Spain
Copyright 2015-2024, Johannes Gutenberg Universitaet Mainz, Germany
This software was partially supported by the
EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu).
This software was partially supported by the
ADA-FS project under the SPPEXA project funded by the DFG.
This file is part of GekkoFS' POSIX interface.
GekkoFS' POSIX interface is free software: you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of the License,
or (at your option) any later version.
GekkoFS' POSIX interface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with GekkoFS' POSIX interface. If not, see
<https://www.gnu.org/licenses/>.
SPDX-License-Identifier: LGPL-3.0-or-later
*/
// This file uses special C formatting for a better overview
// clang-format off
#ifndef GKFS_SYSCALLS_RETS_HPP
#define GKFS_SYSCALLS_RETS_HPP
#include <fmt/format.h>
#include <type_traits>
#include <client/syscalls/detail/syscall_info.h>
namespace gkfs::syscall::ret {
enum class type {
none = ::ret_type_t::rnone,
ptr = ::ret_type_t::rptr,
dec = ::ret_type_t::rdec,
};
/* Some constant definitions for convenience */
static constexpr auto none = type::none;
static constexpr auto ptr = type::ptr;
static constexpr auto dec = type::dec;
template <typename FmtBuffer>
using formatter =
std::add_pointer_t<void(FmtBuffer&, long)>;
template <typename FmtBuffer> inline void
format_none_ret_to(FmtBuffer& buffer, long val);
template <typename FmtBuffer> inline void
format_ptr_ret_to(FmtBuffer& buffer, long val);
template <typename FmtBuffer> inline void
format_dec_ret_to(FmtBuffer& buffer, long val);
template <typename Buffer>
static const constexpr
std::array<formatter<Buffer>, ret_type_max> formatters = {
/* [rnone] = */ format_none_ret_to,
/* [rptr] = */ format_ptr_ret_to,
/* [rdec] = */ format_dec_ret_to,
};
struct desc {
ret::type type_;
ret::type
type() const {
return type_;
}
bool
operator==(ret::type t) const {
return type_ == t;
}
bool
operator!=(ret::type t) const {
return type_ != t;
}
template <typename FmtBuffer>
formatter<FmtBuffer>
formatter() const {
const auto idx = static_cast<int>(type_);
// if the type is unknown fall back to the default formatter
if(idx < 0 || idx >= static_cast<int>(formatters<FmtBuffer>.size())) {
return format_dec_ret_to;
}
assert(formatters<FmtBuffer>.at(idx) != nullptr);
return formatters<FmtBuffer>.at(idx);
}
};
#define LIKELY(x) __builtin_expect(!!(x), 1)
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
template <typename FmtBuffer>
inline void
format_none_ret_to(FmtBuffer& buffer,
long val) {
fmt::format_to(buffer, "void");
}
template <typename FmtBuffer>
inline void
format_ptr_ret_to(FmtBuffer& buffer,
long val) {
if(LIKELY(reinterpret_cast<const void*>(val) != nullptr)) {
fmt::format_to(buffer, "{}", reinterpret_cast<const void*>(val));
return;
}
fmt::format_to(buffer, "NULL");
}
template <typename FmtBuffer>
inline void
format_dec_ret_to(FmtBuffer& buffer,
long val) {
fmt::format_to(buffer, "{}", val);
}
#undef LIKELY
#undef UNLIKELY
} // namespace gkfs::syscall::ret
#endif // GKFS_SYSCALLS_RETS_HPP
// clang-format on