#pragma once #include #include #include namespace saw { template struct is_primitive { constexpr static bool value = false; }; namespace schema { // NOLINTBEGIN /** * Void Type used for function schemas */ struct Void { static constexpr string_literal name = "Void"; }; /** * Boolean type */ struct Bool { static constexpr string_literal name = "Bool"; }; template struct Member { static constexpr string_literal name = "Member"; using ValueType = Schema; static constexpr string_literal KeyLiteral = Literal; }; template struct Map { static constexpr string_literal name = "Map"; using KeyType = Key; using ValueType = Value; }; template struct Struct { static_assert( always_false, "This schema template doesn't support this type of template argument"); }; template struct Struct...> { static constexpr string_literal name = "Struct"; }; template struct Union { static_assert( always_false, "This schema template doesn't support this type of template argument"); }; template struct Union...> { static constexpr string_literal name = "Union"; }; template struct Array { static constexpr string_literal name = "Array"; }; template struct FixedArray { static constexpr string_literal name = "FixedArray"; }; template struct Tuple { static constexpr string_literal name = "Tuple"; }; /** * This acts as a separator of different encodings being mashed together * For example we can transport any base64 encodings in JSON * * using WrappedExample = schema::Tuple< * schema::Wrapper * >; * * data ex_data; */ template class Wrapper { static constexpr string_literal name = "Wrapper"; }; /** * The schema version of ref. * See the Ptr comment on this. */ template class Ref { static constexpr string_literal name = "Ref"; }; /** * The schema version of ptr * It has the advantage that if used in the data class * it won't change the interface of the data instance. * Meaning that data> acts as if it's data * in terms of arithmetic operations. It's mostly useful for arrays of primitive types. * In cases where Array should be translated to a double*. * In that case we still want the data class as an accesor on the array, so we provide the * data> type. */ template class Ptr { static constexpr string_literal name = "Ptr"; }; struct String { static constexpr string_literal name = "String"; }; struct SignedInteger { static constexpr string_literal name = "SignedInteger"; }; struct UnsignedInteger { static constexpr string_literal name = "UnsignedInteger"; }; struct FloatingPoint { static constexpr string_literal name = "FloatingPoint"; }; template struct Primitive { static_assert(((std::is_same_v || std::is_same_v)&&(N == 1 || N == 2 || N == 4 || N == 8)) || (std::is_same_v && (N == 4 || N == 8)), "Primitive Type is not supported"); static constexpr string_literal name = "Primitive"; using InterfaceSchema = Primitive; using StorageSchema = Primitive; }; using Int8 = Primitive; using Int16 = Primitive; using Int32 = Primitive; using Int64 = Primitive; using UInt8 = Primitive; using UInt16 = Primitive; using UInt32 = Primitive; using UInt64 = Primitive; using Float32 = Primitive; using Float64 = Primitive; /** * Classes allowing to distinguish Ints from VarInts */ template struct VariableLengthPrimitive { static constexpr string_literal name = "VariableLengthPrimitive"; }; using VarInt = VariableLengthPrimitive; using VarLong = VariableLengthPrimitive; template struct MixedPrecision { using InterfaceSchema = PrimA; using StorageSchema = PrimB; static_assert(is_primitive::value, "InterfaceSchema needs to be a Primitive"); static_assert(is_primitive::value, "StorageSchema needs to be a Primitive"); }; /** * Classes enabling Rpc calls */ template struct Function { static constexpr string_literal name = "Function"; using RequestT = Request; using ResponseT = Response; }; template struct Interface { static_assert( always_false, "This schema template doesn't support this type of template argument"); static constexpr string_literal name = "Interface"; }; template struct Interface,Names>...> { static constexpr string_literal name = "Interface"; }; // NOLINTEND } // namespace schema template struct schema_has_member{ static_assert( always_false, "Not supported schema case"); }; /** * Checks if identical type exists in schema structure */ template struct schema_has_member> { private: template static constexpr bool value_element() { if constexpr ( i < sizeof...(Members) ){ using MT = typename parameter_pack_type::type; if constexpr ( std::is_same_v ) { return true; } else { return value_element(); } } return false; } public: static constexpr bool value = value_element<0>(); }; /** * */ template struct schema_has_key { static_assert( always_false, "Not supported schema case"); }; template struct schema_has_key> { private: template static constexpr bool value_element() { if constexpr ( i < sizeof...(Members) ){ using MT = typename parameter_pack_type::type; if constexpr ( Key == MT::KeyLiteral ) { return true; }else{ return value_element(); } } return false; } public: static constexpr bool value = value_element<0>(); }; template struct schema_member_index { static_assert( always_false, "Not supported schema case"); }; template struct schema_member_index...>> { static constexpr uint64_t value = parameter_key_pack_index::value; }; template struct schema_member_type { static_assert( always_false, "Not supported schema case"); }; template struct schema_member_type...>> { using type = typename parameter_pack_type...>>::value, MemberVals...>::type; }; template struct is_struct { constexpr static bool value = false; }; template struct is_struct...>> { constexpr static bool value = true; }; template struct is_string { constexpr static bool value = false; }; template <> struct is_string { constexpr static bool value = true; }; template struct is_tuple { constexpr static bool value = false; }; template struct is_tuple> { constexpr static bool value = true; }; template struct is_array { constexpr static bool value = false; }; template struct is_array> { constexpr static bool value = true; }; template struct is_primitive> { constexpr static bool value = true; }; } // namespace saw