sapling/eden/fs/utils/Throw.h
Chad Austin b26418ef01 migrate to throw_ and throwf
Summary:
I've always been annoyed at needing to include folly/Conv.h or fmt to
throw a formatted exception. And while exceptions are rarely in the
hot path, it's still worth having the option to optimize the
formatting and exception allocation step at some point in the future.

I'm sure I missed some, but this diff migrates most of our
`throw T{fmt::format(...)}` patterns to `throwf` and
`throw T{folly::to<std::string>(...)}` to `throw_`.

Reviewed By: genevievehelsel

Differential Revision: D37229822

fbshipit-source-id: c053b5cdaed99e58c485afd2a99be98828f07657
2022-07-08 13:30:53 -07:00

61 lines
1.5 KiB
C++

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
#pragma once
#include <fmt/core.h>
#include <folly/Conv.h>
namespace facebook::eden {
namespace detail {
/**
* Deduplicate the codegen for exception allocation and __cxa_throw /
* _CxxThrowException.
*/
template <typename E>
[[noreturn]] void throw_dedup(const char* what) {
throw E{what};
}
/**
* Deduplicate the codegen for exception allocation and __cxa_throw /
* _CxxThrowException.
*/
template <typename E>
[[noreturn]] void throw_dedup(const std::string& what) {
throw E{what};
}
} // namespace detail
/**
* `throw_<runtime_error>(a, b, c)` is equivalent to `throw
* std::runtime_error(folly::to<std::string>(a, b, c))` but shorter and
* generates less code.
*
* May be very slightly more efficient than `throwf` because it only supports
* concatenation and does not parse a format string.
*/
template <typename E, typename... T>
[[noreturn]] void throw_(T&&... args) {
detail::throw_dedup<E>(folly::to<std::string>(std::forward<T>(args)...));
}
/**
* `throwf<runtime_error>("error: {}", x)` is equivalent to
* `throw std::runtime_error(fmt::format("error: {}", x))` but shorter and
* generates less code.
*/
template <typename E, typename... T>
[[noreturn]] void throwf(fmt::format_string<T...> fmt, T&&... args) {
detail::throw_dedup<E>(fmt::format(std::move(fmt), std::forward<T>(args)...));
}
} // namespace facebook::eden