// Copyright Advanced Micro Devices, Inc., or its affiliates. // SPDX-License-Identifier: MIT #pragma once #include #include namespace rocRoller { namespace Serialization { template struct SameType; template concept CMappedType = requires(T& obj, IO& io, Context& ctx) { {MappingTraits::mapping(io, obj, ctx)}; }; template concept CEmptyMappedType = requires(T& obj, IO& io) { {MappingTraits::mapping(io, obj)}; }; template struct has_MappingTraits { static const bool value = CMappedType; }; template struct has_EmptyMappingTraits { static const bool value = std::same_as && CEmptyMappedType; }; template concept EmptyMappedType = has_EmptyMappingTraits:: value && !has_MappingTraits::value; template class has_EnumTraits { using enumeration = void (*)(IO&, T&); template static uint8_t test(SameType*); template static uint32_t test(...); public: static const bool value = sizeof(test>(nullptr)) == 1; }; template concept EnumType = has_EnumTraits::value; template concept CHasScalarTraits = requires(T const& cval, T& val, std::string const& string) { { ScalarTraits::output(cval) } -> std::convertible_to; {ScalarTraits::input(string, val)}; }; template class has_SequenceTraits { using size = size_t (*)(IO&, T&); template static uint8_t test(SameType*); template static uint32_t test(...); public: static const bool value = sizeof(test>(nullptr)) == 1; }; template concept SequenceType = has_SequenceTraits::value; template class has_CustomMappingTraits { using inputOne = void (*)(IO&, std::string const&, T&); using output = void (*)(IO&, T&); template static uint8_t test(SameType*, SameType*); template static uint32_t test(...); public: static const bool value = sizeof(test>(nullptr, nullptr)) == 1; }; template concept CustomMappingType = has_CustomMappingTraits::value; template struct has_SerializationTraits { static const bool value0 = has_EmptyMappingTraits::value || has_MappingTraits::value; static const bool value1 = has_EnumTraits::value; static const bool value2 = has_SequenceTraits::value; static const bool value3 = has_CustomMappingTraits::value; static const bool value4 = CHasScalarTraits; static const int count = value0 + value1 + value2 + value3 + value4; static_assert(count == 0 || count == 1, "Ambiguous serialization!"); static const bool value = value0 || value1 || value2 || value3 || value4; }; template concept SerializableType = has_SerializationTraits::value; template concept ValueType = !has_SerializationTraits::value; template concept CHasFlowMember = requires { // clang-format off { T::flow } -> std::convertible_to; // clang-format on }; template struct HasFlowValue { static const bool flow = false; }; template struct HasFlowValue { static const bool flow = T::flow; }; /** * Concept that will match a type that has a static `flow` member which is true. It will * not match a type that has no such member, nor will it match if that member is set to * false. It will also not cause an error if it's tested against a type that has no such * member. */ template concept CHasFlow = HasFlowValue::flow; } // namespace Serialization } // namespace rocRoller