diff --git a/src/v/config/bounded_property.h b/src/v/config/bounded_property.h index 6ffddda0389f..3bec797c7792 100644 --- a/src/v/config/bounded_property.h +++ b/src/v/config/bounded_property.h @@ -121,7 +121,7 @@ class bounded_property : public property { // Extract inner value if we are an optional<>, // and pass through into numeric_bounds::validate using outer_type = std::decay_t; - if constexpr (reflection::is_std_optional_v) { + if constexpr (reflection::is_std_optional) { if (new_value.has_value()) { return _bounds.validate(new_value.value()); } else { @@ -147,7 +147,7 @@ class bounded_property : public property { // rather than via admin API. // If T is a std::optional, then need to unpack the value. - if constexpr (reflection::is_std_optional_v) { + if constexpr (reflection::is_std_optional) { if (val.has_value()) { return property::update_value( std::move(_bounds.clamp(val.value()))); @@ -189,7 +189,7 @@ class bounded_property : public property { guess -= guess % _bounds.align.value(); } } else { - if constexpr (reflection::is_std_optional_v) { + if constexpr (reflection::is_std_optional) { if (property::_default.has_value()) { guess = property::_default.value(); } else { @@ -212,4 +212,4 @@ class bounded_property : public property { ss::sstring _example; }; -} // namespace config \ No newline at end of file +} // namespace config diff --git a/src/v/config/property.h b/src/v/config/property.h index 5577b2441505..39fbe2f8afba 100644 --- a/src/v/config/property.h +++ b/src/v/config/property.h @@ -382,7 +382,7 @@ consteval std::string_view property_type_name() { } else if constexpr (std::is_same_v) { // boolean check must come before is_integral check return "boolean"; - } else if constexpr (reflection::is_std_optional_v) { + } else if constexpr (reflection::is_std_optional) { return property_type_name(); } else if constexpr (is_collection) { return property_type_name(); @@ -440,7 +440,7 @@ consteval std::string_view property_units_name() { return "ms"; } else if constexpr (std::is_same_v) { return "s"; - } else if constexpr (reflection::is_std_optional_v) { + } else if constexpr (reflection::is_std_optional) { return property_units_name(); } else { // This will be transformed to nullopt at runtime: returning @@ -471,7 +471,7 @@ std::optional property::units_name() const { template bool property::is_nullable() const { - if constexpr (reflection::is_std_optional_v>) { + if constexpr (reflection::is_std_optional>) { return true; } else { return false; diff --git a/src/v/pandaproxy/parsing/from_chars.h b/src/v/pandaproxy/parsing/from_chars.h index b95baf409fa6..eedddda802a7 100644 --- a/src/v/pandaproxy/parsing/from_chars.h +++ b/src/v/pandaproxy/parsing/from_chars.h @@ -50,11 +50,11 @@ class from_chars { using type = std::decay_t; using result_type = result; - static constexpr bool is_optional = reflection::is_std_optional_v; - static constexpr bool is_named_type = reflection::is_named_type_v; + static constexpr bool is_optional = reflection::is_std_optional; + static constexpr bool is_named_type = reflection::is_rp_named_type; static constexpr bool is_duration = detail::is_duration_v; static constexpr bool is_arithmetic = std::is_arithmetic_v; - static constexpr bool is_ss_bool = reflection::is_ss_bool_v; + static constexpr bool is_ss_bool = reflection::is_ss_bool_class; static constexpr bool is_constructible_from_string_view = std::is_constructible_v; static constexpr bool is_constructible_from_sstring diff --git a/src/v/pandaproxy/parsing/httpd.h b/src/v/pandaproxy/parsing/httpd.h index c725ae5e5969..181675002c6b 100644 --- a/src/v/pandaproxy/parsing/httpd.h +++ b/src/v/pandaproxy/parsing/httpd.h @@ -32,7 +32,7 @@ namespace ppj = pandaproxy::json; template T parse_param(std::string_view type, std::string_view key, ss::sstring value) { - if (!reflection::is_std_optional_v && value.empty()) { + if (!reflection::is_std_optional && value.empty()) { throw error( error_code::empty_param, fmt::format("Missing mandatory {} '{}'", type, key)); diff --git a/src/v/reflection/adl.h b/src/v/reflection/adl.h index 56f39c43d4f1..f3116c47599f 100644 --- a/src/v/reflection/adl.h +++ b/src/v/reflection/adl.h @@ -30,10 +30,10 @@ namespace reflection { template struct adl { using type = std::remove_reference_t>; - static constexpr bool is_optional = is_std_optional_v; + static constexpr bool is_optional = is_std_optional; static constexpr bool is_sstring = std::is_same_v; - static constexpr bool is_vector = is_std_vector_v; - static constexpr bool is_named_type = is_named_type_v; + static constexpr bool is_vector = is_std_vector; + static constexpr bool is_named_type = is_rp_named_type; static constexpr bool is_iobuf = std::is_same_v; static constexpr bool is_standard_layout = std::is_standard_layout_v; static constexpr bool is_not_floating_point @@ -41,12 +41,12 @@ struct adl { static constexpr bool is_trivially_copyable = std::is_trivially_copyable_v; static constexpr bool is_enum = std::is_enum_v; - static constexpr bool is_ss_bool = is_ss_bool_v; + static constexpr bool is_ss_bool = is_ss_bool_class; static constexpr bool is_chrono_milliseconds = std::is_same_v; static constexpr bool is_time_point = std::is_same_v; - static constexpr bool is_circular_buffer = is_ss_circular_buffer_v; + static constexpr bool is_circular_buffer = is_ss_circular_buffer; static_assert( is_optional || is_sstring || is_vector || is_named_type || is_iobuf diff --git a/src/v/reflection/type_traits.h b/src/v/reflection/type_traits.h index e910f7b5cfe4..fa7a815fb769 100644 --- a/src/v/reflection/type_traits.h +++ b/src/v/reflection/type_traits.h @@ -22,48 +22,38 @@ #include #include +namespace detail { + +template class C> +struct is_specialization_of : std::false_type {}; +template class C, typename... Args> +struct is_specialization_of, C> : std::true_type {}; +template class C> +inline constexpr bool is_specialization_of_v + = is_specialization_of::value; + +} // namespace detail + namespace reflection { template -struct is_std_vector : std::false_type {}; -template -struct is_std_vector> : std::true_type {}; -template -inline constexpr bool is_std_vector_v = is_std_vector::value; +concept is_std_vector = ::detail::is_specialization_of_v; template -struct is_ss_circular_buffer : std::false_type {}; -template -struct is_ss_circular_buffer> : std::true_type {}; -template -inline constexpr bool is_ss_circular_buffer_v = is_ss_circular_buffer::value; +concept is_ss_circular_buffer + = ::detail::is_specialization_of_v; template -struct is_std_optional : std::false_type {}; -template -struct is_std_optional> : std::true_type {}; -template -inline constexpr bool is_std_optional_v = is_std_optional::value; +concept is_std_optional = ::detail::is_specialization_of_v; template -struct is_named_type : std::false_type {}; -template -struct is_named_type> : std::true_type {}; -template -inline constexpr bool is_named_type_v = is_named_type::value; +concept is_rp_named_type + = ::detail::is_specialization_of_v; template -struct is_ss_bool : std::false_type {}; -template -struct is_ss_bool> : std::true_type {}; -template -inline constexpr bool is_ss_bool_v = is_ss_bool::value; +concept is_ss_bool_class = ::detail::is_specialization_of_v; template -struct is_tristate : std::false_type {}; -template -struct is_tristate> : std::true_type {}; -template -inline constexpr bool is_tristate_v = is_tristate::value; +concept is_tristate = ::detail::is_specialization_of_v; } // namespace reflection diff --git a/src/v/serde/serde.h b/src/v/serde/serde.h index 5fb9c76d00e7..304f1ecba9ca 100644 --- a/src/v/serde/serde.h +++ b/src/v/serde/serde.h @@ -99,33 +99,33 @@ using serde_size_t = uint16_t; using serde_size_t = uint32_t; #endif -template -struct is_fragmented_vector : std::false_type {}; -template -struct is_fragmented_vector> : std::true_type {}; -template -inline constexpr bool is_fragmented_vector_v = is_fragmented_vector::value; +namespace detail { -template -struct is_std_unordered_map : std::false_type {}; -template -struct is_std_unordered_map> : std::true_type {}; -template -inline constexpr bool is_std_unordered_map_v = is_std_unordered_map::value; +template class C> +struct is_specialization_of_sized : std::false_type {}; +template class C, class T, size_t N> +struct is_specialization_of_sized, C> : std::true_type {}; +template class C> +inline constexpr bool is_specialization_of_sized_v + = is_specialization_of_sized::value; + +} // namespace detail template -struct is_absl_node_hash_set : std::false_type {}; -template -struct is_absl_node_hash_set> : std::true_type {}; +concept is_fragmented_vector + = detail::is_specialization_of_sized_v; + template -inline constexpr bool is_absl_node_hash_set_v = is_absl_node_hash_set::value; +concept is_std_unordered_map + = ::detail::is_specialization_of_v; template -struct is_absl_node_hash_map : std::false_type {}; -template -struct is_absl_node_hash_map> : std::true_type {}; +concept is_absl_node_hash_set + = ::detail::is_specialization_of_v; + template -inline constexpr bool is_absl_node_hash_map_v = is_absl_node_hash_map::value; +concept is_absl_node_hash_map + = ::detail::is_specialization_of_v; template inline constexpr auto const is_serde_compatible_v @@ -134,18 +134,18 @@ inline constexpr auto const is_serde_compatible_v && (!std::is_same_v || std::numeric_limits::is_iec559) && (!std::is_same_v || std::numeric_limits::is_iec559) && (!serde_is_enum_v || sizeof(std::decay_t) <= sizeof(serde_enum_serialized_t))) - || reflection::is_std_vector_v - || reflection::is_named_type_v - || reflection::is_ss_bool_v - || reflection::is_std_optional_v + || reflection::is_std_vector + || reflection::is_rp_named_type + || reflection::is_ss_bool_class + || reflection::is_std_optional || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v - || is_absl_node_hash_set_v - || is_absl_node_hash_map_v - || is_std_unordered_map_v - || is_fragmented_vector_v || reflection::is_tristate_v || std::is_same_v; + || is_absl_node_hash_set + || is_absl_node_hash_map + || is_std_unordered_map + || is_fragmented_vector || reflection::is_tristate || std::is_same_v; template inline constexpr auto const are_bytes_and_string_different = !( @@ -234,7 +234,7 @@ void write(iobuf& out, T t) { static_assert(sizeof(le_t) == sizeof(Type)); out.append(reinterpret_cast(&le_t), sizeof(le_t)); } - } else if constexpr (reflection::is_std_vector_v) { + } else if constexpr (reflection::is_std_vector) { if (unlikely(t.size() > std::numeric_limits::max())) { throw serde_exception(fmt_with_ctx( ssx::sformat, @@ -245,9 +245,9 @@ void write(iobuf& out, T t) { for (auto& el : t) { write(out, std::move(el)); } - } else if constexpr (reflection::is_named_type_v) { + } else if constexpr (reflection::is_rp_named_type) { return write(out, static_cast(t)); - } else if constexpr (reflection::is_ss_bool_v) { + } else if constexpr (reflection::is_ss_bool_class) { write(out, static_cast(bool(t))); } else if constexpr (std::is_same_v) { write(out, t.count()); @@ -260,14 +260,14 @@ void write(iobuf& out, T t) { } else if constexpr (std::is_same_v) { write(out, t.size()); out.append(t.data(), t.size()); - } else if constexpr (reflection::is_std_optional_v) { + } else if constexpr (reflection::is_std_optional) { if (t) { write(out, true); write(out, std::move(t.value())); } else { write(out, false); } - } else if constexpr (is_absl_node_hash_set_v) { + } else if constexpr (is_absl_node_hash_set) { if (unlikely(t.size() > std::numeric_limits::max())) { throw serde_exception(fmt_with_ctx( ssx::sformat, @@ -278,7 +278,7 @@ void write(iobuf& out, T t) { for (auto& e : t) { write(out, e); } - } else if constexpr (is_absl_node_hash_map_v) { + } else if constexpr (is_absl_node_hash_map) { if (unlikely(t.size() > std::numeric_limits::max())) { throw serde_exception(fmt_with_ctx( ssx::sformat, @@ -290,7 +290,7 @@ void write(iobuf& out, T t) { write(out, v.first); write(out, std::move(v.second)); } - } else if constexpr (is_std_unordered_map_v) { + } else if constexpr (is_std_unordered_map) { if (unlikely(t.size() > std::numeric_limits::max())) { throw serde_exception(fmt_with_ctx( ssx::sformat, @@ -302,7 +302,7 @@ void write(iobuf& out, T t) { write(out, v.first); write(out, std::move(v.second)); } - } else if constexpr (is_fragmented_vector_v) { + } else if constexpr (is_fragmented_vector) { if (unlikely(t.size() > std::numeric_limits::max())) { throw serde_exception(fmt_with_ctx( ssx::sformat, @@ -313,7 +313,7 @@ void write(iobuf& out, T t) { for (auto& el : t) { write(out, std::move(el)); } - } else if constexpr (reflection::is_tristate_v) { + } else if constexpr (reflection::is_tristate) { if (t.is_disabled()) { write(out, -1); } else if (!t.has_value()) { @@ -496,16 +496,16 @@ void read_nested(iobuf_parser& in, T& t, std::size_t const bytes_left_limit) { } else { t = ss::le_to_cpu(in.consume_type()); } - } else if constexpr (reflection::is_std_vector_v) { + } else if constexpr (reflection::is_std_vector) { using value_type = typename Type::value_type; const auto size = read_nested(in, bytes_left_limit); t.reserve(size); for (auto i = 0U; i < size; ++i) { t.push_back(read_nested(in, bytes_left_limit)); } - } else if constexpr (reflection::is_named_type_v) { + } else if constexpr (reflection::is_rp_named_type) { t = Type{read_nested(in, bytes_left_limit)}; - } else if constexpr (reflection::is_ss_bool_v) { + } else if constexpr (reflection::is_ss_bool_class) { t = Type{read_nested(in, bytes_left_limit) != 0}; } else if constexpr (std::is_same_v) { t = std::chrono::milliseconds{ @@ -522,12 +522,12 @@ void read_nested(iobuf_parser& in, T& t, std::size_t const bytes_left_limit) { read_nested(in, bytes_left_limit)); in.consume_to(str.size(), str.begin()); t = str; - } else if constexpr (reflection::is_std_optional_v) { + } else if constexpr (reflection::is_std_optional) { t = read_nested(in, bytes_left_limit) ? Type{read_nested( in, bytes_left_limit)} : std::nullopt; - } else if constexpr (is_absl_node_hash_set_v) { + } else if constexpr (is_absl_node_hash_set) { const auto size = read_nested(in, bytes_left_limit); t.reserve(size); for (auto i = 0U; i < size; ++i) { @@ -535,7 +535,7 @@ void read_nested(iobuf_parser& in, T& t, std::size_t const bytes_left_limit) { in, bytes_left_limit); t.emplace(std::move(elem)); } - } else if constexpr (is_absl_node_hash_map_v) { + } else if constexpr (is_absl_node_hash_map) { const auto size = read_nested(in, bytes_left_limit); t.reserve(size); for (auto i = 0U; i < size; ++i) { @@ -545,7 +545,7 @@ void read_nested(iobuf_parser& in, T& t, std::size_t const bytes_left_limit) { in, bytes_left_limit); t.emplace(std::move(key), std::move(value)); } - } else if constexpr (is_std_unordered_map_v) { + } else if constexpr (is_std_unordered_map) { const auto size = read_nested(in, bytes_left_limit); t.reserve(size); for (auto i = 0U; i < size; ++i) { @@ -555,14 +555,14 @@ void read_nested(iobuf_parser& in, T& t, std::size_t const bytes_left_limit) { in, bytes_left_limit); t.emplace(std::move(key), std::move(value)); } - } else if constexpr (is_fragmented_vector_v) { + } else if constexpr (is_fragmented_vector) { using value_type = typename Type::value_type; const auto size = read_nested(in, bytes_left_limit); for (auto i = 0U; i < size; ++i) { t.push_back(read_nested(in, bytes_left_limit)); } t.shrink_to_fit(); - } else if constexpr (reflection::is_tristate_v) { + } else if constexpr (reflection::is_tristate) { int8_t flag = read_nested(in, bytes_left_limit); if (flag == -1) { // disabled diff --git a/src/v/serde/test/fuzz.cc b/src/v/serde/test/fuzz.cc index 115dc184a9cf..3311f24975a8 100644 --- a/src/v/serde/test/fuzz.cc +++ b/src/v/serde/test/fuzz.cc @@ -71,7 +71,7 @@ void init( }, t.template get_generation())), ...); - } else if constexpr (reflection::is_std_optional_v) { + } else if constexpr (reflection::is_std_optional) { if ( depth != max_depth && gen.get() @@ -81,7 +81,7 @@ void init( } else { t = std::nullopt; } - } else if constexpr (reflection::is_std_vector_v) { + } else if constexpr (reflection::is_std_vector) { if (depth != max_depth) { t.resize(gen.get() % max_vector_size); for (auto& v : t) {