Commit 0eb5ac54 by Samuel Benzaquen Committed by Copybara-Service

Improve compiler errors for mismatched ParsedFormat inputs.

PiperOrigin-RevId: 448582508
Change-Id: I67fbff5f42a083e093ea2c20749e073ca03feb0b
parent f7a250aa
...@@ -1116,6 +1116,7 @@ cc_library( ...@@ -1116,6 +1116,7 @@ cc_library(
"//absl/numeric:representation", "//absl/numeric:representation",
"//absl/types:optional", "//absl/types:optional",
"//absl/types:span", "//absl/types:span",
"//absl/utility",
], ],
) )
......
...@@ -414,6 +414,7 @@ absl_cc_library( ...@@ -414,6 +414,7 @@ absl_cc_library(
absl::core_headers absl::core_headers
absl::numeric_representation absl::numeric_representation
absl::type_traits absl::type_traits
absl::utility
absl::int128 absl::int128
absl::span absl::span
) )
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "absl/strings/internal/str_format/checker.h" #include "absl/strings/internal/str_format/checker.h"
#include "absl/strings/internal/str_format/parser.h" #include "absl/strings/internal/str_format/parser.h"
#include "absl/types/span.h" #include "absl/types/span.h"
#include "absl/utility/utility.h"
namespace absl { namespace absl {
ABSL_NAMESPACE_BEGIN ABSL_NAMESPACE_BEGIN
...@@ -87,6 +88,36 @@ class FormatSpecTemplate ...@@ -87,6 +88,36 @@ class FormatSpecTemplate
: public MakeDependent<UntypedFormatSpec, Args...>::type { : public MakeDependent<UntypedFormatSpec, Args...>::type {
using Base = typename MakeDependent<UntypedFormatSpec, Args...>::type; using Base = typename MakeDependent<UntypedFormatSpec, Args...>::type;
template <bool res>
struct ErrorMaker {
constexpr bool operator()(int) const { return res; }
};
template <int i, int j>
static constexpr bool CheckArity(ErrorMaker<true> SpecifierCount = {},
ErrorMaker<i == j> ParametersPassed = {}) {
static_assert(SpecifierCount(i) == ParametersPassed(j),
"Number of arguments passed must match the number of "
"conversion specifiers.");
return true;
}
template <FormatConversionCharSet specified, FormatConversionCharSet passed,
int arg>
static constexpr bool CheckMatch(
ErrorMaker<Contains(specified, passed)> MismatchedArgumentNumber = {}) {
static_assert(MismatchedArgumentNumber(arg),
"Passed argument must match specified format.");
return true;
}
template <FormatConversionCharSet... C, size_t... I>
static bool CheckMatches(absl::index_sequence<I...>) {
bool res[] = {true, CheckMatch<Args, C, I + 1>()...};
(void)res;
return true;
}
public: public:
#ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER #ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
...@@ -133,13 +164,12 @@ class FormatSpecTemplate ...@@ -133,13 +164,12 @@ class FormatSpecTemplate
#endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER #endif // ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
template < template <FormatConversionCharSet... C>
FormatConversionCharSet... C,
typename = typename std::enable_if<sizeof...(C) == sizeof...(Args)>::type,
typename = typename std::enable_if<AllOf(Contains(Args,
C)...)>::type>
FormatSpecTemplate(const ExtendedParsedFormat<C...>& pc) // NOLINT FormatSpecTemplate(const ExtendedParsedFormat<C...>& pc) // NOLINT
: Base(&pc) {} : Base(&pc) {
CheckArity<sizeof...(C), sizeof...(Args)>();
CheckMatches<C...>(absl::make_index_sequence<sizeof...(C)>{});
}
}; };
class Streamable { class Streamable {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment