@@ -378,9 +378,11 @@ auto compiler_draft4_validation_type(const Context &context,
378378
379379 return {make (sourcemeta::blaze::InstructionIndex::AssertionTypeStrictAny,
380380 context, schema_context, dynamic_context,
381- std::vector<sourcemeta::core::JSON::Type>{
382- sourcemeta::core::JSON::Type::Real,
383- sourcemeta::core::JSON::Type::Integer})};
381+ static_cast <ValueTypes>(
382+ (1U << static_cast <std::uint8_t >(
383+ sourcemeta::core::JSON::Type::Real)) |
384+ (1U << static_cast <std::uint8_t >(
385+ sourcemeta::core::JSON::Type::Integer))))};
384386 } else if (type == " integer" ) {
385387 if (context.mode == Mode::FastValidation &&
386388 schema_context.schema .defines (" enum" ) &&
@@ -455,9 +457,11 @@ auto compiler_draft4_validation_type(const Context &context,
455457 } else if (type == " number" ) {
456458 return {make (sourcemeta::blaze::InstructionIndex::AssertionTypeStrictAny,
457459 context, schema_context, dynamic_context,
458- std::vector<sourcemeta::core::JSON::Type>{
459- sourcemeta::core::JSON::Type::Real,
460- sourcemeta::core::JSON::Type::Integer})};
460+ static_cast <ValueTypes>(
461+ (1U << static_cast <std::uint8_t >(
462+ sourcemeta::core::JSON::Type::Real)) |
463+ (1U << static_cast <std::uint8_t >(
464+ sourcemeta::core::JSON::Type::Integer))))};
461465 } else if (type == " integer" ) {
462466 return {make (sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,
463467 context, schema_context, dynamic_context,
@@ -470,33 +474,40 @@ auto compiler_draft4_validation_type(const Context &context,
470474 return {};
471475 }
472476 } else if (schema_context.schema .at (dynamic_context.keyword ).is_array ()) {
473- std::vector<sourcemeta::core::JSON::Type> types;
477+ ValueTypes types{ 0 } ;
474478 for (const auto &type :
475479 schema_context.schema .at (dynamic_context.keyword ).as_array ()) {
476480 assert (type.is_string ());
477481 const auto &type_string{type.to_string ()};
478482 if (type_string == " null" ) {
479- types.push_back (sourcemeta::core::JSON::Type::Null);
483+ types |= (1U << static_cast <std::uint8_t >(
484+ sourcemeta::core::JSON::Type::Null));
480485 } else if (type_string == " boolean" ) {
481- types.push_back (sourcemeta::core::JSON::Type::Boolean);
486+ types |= (1U << static_cast <std::uint8_t >(
487+ sourcemeta::core::JSON::Type::Boolean));
482488 } else if (type_string == " object" ) {
483- types.push_back (sourcemeta::core::JSON::Type::Object);
489+ types |= (1U << static_cast <std::uint8_t >(
490+ sourcemeta::core::JSON::Type::Object));
484491 } else if (type_string == " array" ) {
485- types.push_back (sourcemeta::core::JSON::Type::Array);
492+ types |= (1U << static_cast <std::uint8_t >(
493+ sourcemeta::core::JSON::Type::Array));
486494 } else if (type_string == " number" ) {
487- types.push_back (sourcemeta::core::JSON::Type::Integer);
488- types.push_back (sourcemeta::core::JSON::Type::Real);
495+ types |= (1U << static_cast <std::uint8_t >(
496+ sourcemeta::core::JSON::Type::Integer));
497+ types |= (1U << static_cast <std::uint8_t >(
498+ sourcemeta::core::JSON::Type::Real));
489499 } else if (type_string == " integer" ) {
490- types.push_back (sourcemeta::core::JSON::Type::Integer);
500+ types |= (1U << static_cast <std::uint8_t >(
501+ sourcemeta::core::JSON::Type::Integer));
491502 } else if (type_string == " string" ) {
492- types.push_back (sourcemeta::core::JSON::Type::String);
503+ types |= (1U << static_cast <std::uint8_t >(
504+ sourcemeta::core::JSON::Type::String));
493505 }
494506 }
495507
496- assert (types.size () >=
497- schema_context.schema .at (dynamic_context.keyword ).size ());
508+ assert (types != 0 );
498509 return {make (sourcemeta::blaze::InstructionIndex::AssertionTypeStrictAny,
499- context, schema_context, dynamic_context, std::move ( types) )};
510+ context, schema_context, dynamic_context, types)};
500511 }
501512
502513 return {};
@@ -703,33 +714,39 @@ auto compiler_draft4_applicator_anyof(const Context &context,
703714 sourcemeta::blaze::InstructionIndex::
704715 AssertionTypeStrictAny);
705716 })) {
706- ValueTypes types;
717+ ValueTypes types{ 0 } ;
707718 for (const auto &instruction : disjunctors) {
708719 if (instruction.children .front ().type ==
709720 sourcemeta::blaze::InstructionIndex::AssertionTypeStrict) {
710721 const auto &value{
711722 *std::get_if<ValueType>(&instruction.children .front ().value )};
712- types. push_back ( value);
723+ types |= ( 1U << static_cast <std:: uint8_t >( value) );
713724 }
714725
715726 if (instruction.children .front ().type ==
716727 sourcemeta::blaze::InstructionIndex::AssertionTypeStrictAny) {
717728 const auto &value{
718729 *std::get_if<ValueTypes>(&instruction.children .front ().value )};
719- for (const auto type : value) {
720- types.push_back (type);
721- }
730+ types |= value;
722731 }
723732 }
724733
725- assert (!types.empty ());
726- if (types.size () > 1 ) {
734+ assert (types != 0 );
735+ std::uint8_t popcount{0 };
736+ for (std::uint8_t temp{types}; temp != 0 ; temp >>= 1 ) {
737+ popcount += (temp & 1 );
738+ }
739+ if (popcount > 1 ) {
727740 return {make (sourcemeta::blaze::InstructionIndex::AssertionTypeStrictAny,
728- context, schema_context, dynamic_context, std::move ( types) )};
741+ context, schema_context, dynamic_context, types)};
729742 } else {
743+ std::uint8_t type_index{0 };
744+ for (std::uint8_t temp{types}; (temp & 1 ) == 0 ; temp >>= 1 ) {
745+ type_index++;
746+ }
730747 return {make (sourcemeta::blaze::InstructionIndex::AssertionTypeStrict,
731748 context, schema_context, dynamic_context,
732- ValueType{*types. cbegin ()} )};
749+ static_cast < ValueType>(type_index) )};
733750 }
734751 }
735752
0 commit comments