#ifndef RFL_INTERNAL_HASFIELDS_HPP_ #define RFL_INTERNAL_HASFIELDS_HPP_ #include #include #include #include "all_fields.hpp" #include "is_field.hpp" #include "is_flatten_field.hpp" #include "ptr_tuple_t.hpp" namespace rfl { namespace internal { template constexpr bool all_fields_or_flatten() { if constexpr (_i == std::tuple_size_v) { return true; } else { using T = std::remove_cvref_t>; if constexpr (is_flatten_field_v) { return all_fields_or_flatten::Type>>() && all_fields_or_flatten(); } else { return is_field_v && all_fields_or_flatten(); } } } template constexpr bool some_fields_or_flatten() { if constexpr (_i == std::tuple_size_v) { return false; } else { using T = std::remove_cvref_t>; if constexpr (is_flatten_field_v) { return some_fields_or_flatten::Type>>() || some_fields_or_flatten(); } else { return is_field_v || some_fields_or_flatten(); } } } template constexpr bool has_fields() { if constexpr (is_named_tuple_v) { return true; } else { using TupleType = ptr_tuple_t; if constexpr (some_fields_or_flatten()) { static_assert( all_fields_or_flatten(), "If some of your fields are annotated using rfl::Field<...>, " "then you must annotate all of your fields. " "Also, you cannot combine annotated and " "unannotated fields using rfl::Flatten<...>." ); return true; } else { return false; } } } } // namespace internal } // namespace rfl #endif