/* This file is generated by tools/stackvm_gen/IsaGen at 9/20/2023 10:17:07 AM
 * +00:00.
 *
 * Copyright 2019-2021 Canaan Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#pragma once
#include "../error.h"
#include "../result.h"
#include "../span_reader.h"
#include "opcode.h"

BEGIN_NS_NNCASE_RT_MODULE(stackvm)

template <opcode_t Op> struct op_reader;

template <> struct op_reader<opcode_t::NOP> {
    nop_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        nop_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::BR> {
    br_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        br_op_t op;
        op.target = reader.read_unaligned<int32_t>();
        return op;
    }
};

template <> struct op_reader<opcode_t::BR_TRUE> {
    br_true_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        br_true_op_t op;
        op.target = reader.read_unaligned<int32_t>();
        return op;
    }
};

template <> struct op_reader<opcode_t::BR_FALSE> {
    br_false_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        br_false_op_t op;
        op.target = reader.read_unaligned<int32_t>();
        return op;
    }
};

template <> struct op_reader<opcode_t::RET> {
    ret_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ret_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CALL> {
    call_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        call_op_t op;
        op.args = reader.read_unaligned<uint16_t>();
        op.target = reader.read_unaligned<int32_t>();
        return op;
    }
};

template <> struct op_reader<opcode_t::ECALL> {
    ecall_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ecall_op_t op;
        op.args = reader.read_unaligned<uint16_t>();
        return op;
    }
};

template <> struct op_reader<opcode_t::EXTCALL> {
    extcall_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        extcall_op_t op;
        op.args = reader.read_unaligned<uint16_t>();
        op.is_prim_func = reader.read_unaligned<bool>();
        return op;
    }
};

template <> struct op_reader<opcode_t::CUSCALL> {
    cuscall_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        cuscall_op_t op;
        op.registered_name = reader.read_string();
        op.fields_span = reader.read_span(reader.read_unaligned<uint32_t>());
        op.args = reader.read_unaligned<uint16_t>();
        return op;
    }
};

template <> struct op_reader<opcode_t::THROW> {
    throw_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        throw_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::BREAK> {
    break_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        break_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDC_I4> {
    ldc_i4_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldc_i4_op_t op;
        op.imm = reader.read_unaligned<int32_t>();
        return op;
    }
};

template <> struct op_reader<opcode_t::LDNULL> {
    ldnull_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldnull_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDC_I4_0> {
    ldc_i4_0_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldc_i4_0_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDC_I4_1> {
    ldc_i4_1_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldc_i4_1_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDC_R4> {
    ldc_r4_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldc_r4_op_t op;
        op.imm = reader.read_unaligned<float>();
        return op;
    }
};

template <> struct op_reader<opcode_t::LDIND_I1> {
    ldind_i1_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldind_i1_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDIND_I2> {
    ldind_i2_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldind_i2_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDIND_I4> {
    ldind_i4_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldind_i4_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDIND_I> {
    ldind_i_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldind_i_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDIND_U1> {
    ldind_u1_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldind_u1_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDIND_U2> {
    ldind_u2_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldind_u2_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDIND_U4> {
    ldind_u4_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldind_u4_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDIND_U> {
    ldind_u_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldind_u_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDIND_BR2> {
    ldind_br2_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldind_br2_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDIND_R4> {
    ldind_r4_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldind_r4_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::STIND_I1> {
    stind_i1_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        stind_i1_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::STIND_I2> {
    stind_i2_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        stind_i2_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::STIND_I4> {
    stind_i4_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        stind_i4_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::STIND_I> {
    stind_i_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        stind_i_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::STIND_BR2> {
    stind_br2_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        stind_br2_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::STIND_R4> {
    stind_r4_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        stind_r4_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LEA_GP> {
    lea_gp_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        lea_gp_op_t op;
        op.gpid = reader.read_unaligned<uint8_t>();
        op.offset = reader.read_unaligned<int32_t>();
        return op;
    }
};

template <> struct op_reader<opcode_t::LDELEM_I1> {
    ldelem_i1_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldelem_i1_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDELEM_I2> {
    ldelem_i2_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldelem_i2_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDELEM_I4> {
    ldelem_i4_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldelem_i4_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDELEM_I> {
    ldelem_i_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldelem_i_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDELEM_U1> {
    ldelem_u1_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldelem_u1_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDELEM_U2> {
    ldelem_u2_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldelem_u2_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDELEM_U4> {
    ldelem_u4_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldelem_u4_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDELEM_U> {
    ldelem_u_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldelem_u_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDELEM_BR2> {
    ldelem_br2_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldelem_br2_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDELEM_R4> {
    ldelem_r4_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldelem_r4_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::STELEM_I1> {
    stelem_i1_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        stelem_i1_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::STELEM_I2> {
    stelem_i2_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        stelem_i2_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::STELEM_I4> {
    stelem_i4_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        stelem_i4_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::STELEM_I> {
    stelem_i_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        stelem_i_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::STELEM_BR2> {
    stelem_br2_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        stelem_br2_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::STELEM_R4> {
    stelem_r4_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        stelem_r4_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDARG> {
    ldarg_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldarg_op_t op;
        op.index = reader.read_unaligned<uint16_t>();
        return op;
    }
};

template <> struct op_reader<opcode_t::LDARG_0> {
    ldarg_0_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldarg_0_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDARG_1> {
    ldarg_1_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldarg_1_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDARG_2> {
    ldarg_2_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldarg_2_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDARG_3> {
    ldarg_3_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldarg_3_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDARG_4> {
    ldarg_4_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldarg_4_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDARG_5> {
    ldarg_5_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldarg_5_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDTUPLE_ELEM> {
    ldtuple_elem_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldtuple_elem_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDTUPLE> {
    ldtuple_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldtuple_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDDATATYPE> {
    lddatatype_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        lddatatype_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDTENSOR> {
    ldtensor_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldtensor_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::LDLOCAL> {
    ldlocal_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldlocal_op_t op;
        op.index = reader.read_unaligned<uint16_t>();
        return op;
    }
};

template <> struct op_reader<opcode_t::STLOCAL> {
    stlocal_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        stlocal_op_t op;
        op.index = reader.read_unaligned<uint16_t>();
        return op;
    }
};

template <> struct op_reader<opcode_t::LDSCALAR> {
    ldscalar_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ldscalar_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::DUP> {
    dup_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        dup_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::POP> {
    pop_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        pop_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::NEG> {
    neg_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        neg_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::ADD> {
    add_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        add_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::SUB> {
    sub_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        sub_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::MUL> {
    mul_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        mul_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::DIV> {
    div_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        div_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::DIV_U> {
    div_u_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        div_u_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::REM> {
    rem_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        rem_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::REM_U> {
    rem_u_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        rem_u_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::AND> {
    and_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        and_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::OR> {
    or_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        or_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::XOR> {
    xor_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        xor_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::NOT> {
    not_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        not_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::SHL> {
    shl_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        shl_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::SHR> {
    shr_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        shr_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::SHR_U> {
    shr_u_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        shr_u_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CLT> {
    clt_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        clt_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CLT_U> {
    clt_u_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        clt_u_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CLE> {
    cle_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        cle_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CLE_U> {
    cle_u_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        cle_u_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CEQ> {
    ceq_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        ceq_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CGE> {
    cge_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        cge_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CGE_U> {
    cge_u_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        cge_u_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CGT> {
    cgt_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        cgt_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CGT_U> {
    cgt_u_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        cgt_u_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CNE> {
    cne_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        cne_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CONV_I1> {
    conv_i1_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        conv_i1_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CONV_I2> {
    conv_i2_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        conv_i2_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CONV_I4> {
    conv_i4_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        conv_i4_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CONV_I> {
    conv_i_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        conv_i_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CONV_U1> {
    conv_u1_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        conv_u1_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CONV_U2> {
    conv_u2_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        conv_u2_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CONV_U4> {
    conv_u4_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        conv_u4_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CONV_U> {
    conv_u_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        conv_u_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CONV_BR2> {
    conv_br2_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        conv_br2_op_t op;
        return op;
    }
};

template <> struct op_reader<opcode_t::CONV_R4> {
    conv_r4_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        conv_r4_op_t op;
        return op;
    }
};

template <tensor_function_t Op> struct tensor_op_reader;

template <> struct tensor_op_reader<tensor_function_t::batch_normalization> {
    tensor_batch_normalization_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_batch_normalization_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::batch_to_space> {
    tensor_batch_to_space_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_batch_to_space_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::binary> {
    tensor_binary_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_binary_op_t op;
        op.binary_op =
            static_cast<binary_op_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::bitcast> {
    tensor_bitcast_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_bitcast_op_t op;
        op.type = reader.read_unaligned<prim_type_t>();
        op.new_type = reader.read_unaligned<prim_type_t>();
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::broadcast> {
    tensor_broadcast_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_broadcast_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::broadcast_shape> {
    tensor_broadcast_shape_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_broadcast_shape_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::bucket_pad> {
    tensor_bucket_pad_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_bucket_pad_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::cast> {
    tensor_cast_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_cast_op_t op;
        op.new_type = static_cast<typecode_t>(reader.read_unaligned<uint8_t>());
        op.cast_mode =
            static_cast<cast_mode_t>(reader.read_unaligned<uint32_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::celu> {
    tensor_celu_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_celu_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::clamp> {
    tensor_clamp_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_clamp_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::compare> {
    tensor_compare_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_compare_op_t op;
        op.compare_op =
            static_cast<compare_op_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::concat> {
    tensor_concat_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_concat_op_t op;
        op.axis = reader.read_unaligned<int32_t>();
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::condition> {
    tensor_condition_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_condition_op_t op;
        op.can_fold_const_call = reader.read_unaligned<bool>();
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::constant_of_shape> {
    tensor_constant_of_shape_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_constant_of_shape_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::conv2d> {
    tensor_conv2d_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_conv2d_op_t op;
        op.pad_mode = static_cast<pad_mode_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::conv2d_shape> {
    tensor_conv2d_shape_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_conv2d_shape_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::conv2d_transpose> {
    tensor_conv2d_transpose_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_conv2d_transpose_op_t op;
        op.pad_mode = static_cast<pad_mode_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::conv2d_transpose_shape> {
    tensor_conv2d_transpose_shape_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_conv2d_transpose_shape_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::cum_sum> {
    tensor_cum_sum_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_cum_sum_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::dequantize> {
    tensor_dequantize_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_dequantize_op_t op;
        op.target_type =
            static_cast<typecode_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::elu> {
    tensor_elu_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_elu_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::erf> {
    tensor_erf_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_erf_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::expand> {
    tensor_expand_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_expand_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::fake_dequantize> {
    tensor_fake_dequantize_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_fake_dequantize_op_t op;
        op.target_type =
            static_cast<typecode_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::fake_quantize> {
    tensor_fake_quantize_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_fake_quantize_op_t op;
        op.target_type =
            static_cast<typecode_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::fix_shape> {
    tensor_fix_shape_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_fix_shape_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::flatten> {
    tensor_flatten_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_flatten_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::gather> {
    tensor_gather_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_gather_op_t op;
        op.axis = reader.read_unaligned<int32_t>();
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::gather_elements> {
    tensor_gather_elements_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_gather_elements_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::gather_nd> {
    tensor_gather_nd_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_gather_nd_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::gelu> {
    tensor_gelu_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_gelu_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::get_item> {
    tensor_get_item_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_get_item_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::get_paddings> {
    tensor_get_paddings_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_get_paddings_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::hard_sigmoid> {
    tensor_hard_sigmoid_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_hard_sigmoid_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::hard_swish> {
    tensor_hard_swish_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_hard_swish_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::hardmax> {
    tensor_hardmax_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_hardmax_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::index_of> {
    tensor_index_of_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_index_of_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::instance_normalization> {
    tensor_instance_normalization_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_instance_normalization_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::l2_normalization> {
    tensor_l2_normalization_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_l2_normalization_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::layer_norm> {
    tensor_layer_norm_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_layer_norm_op_t op;
        op.axis = reader.read_unaligned<int32_t>();
        op.epsilon = reader.read_unaligned<float>();
        op.use_mean = reader.read_unaligned<bool>();
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::leaky_relu> {
    tensor_leaky_relu_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_leaky_relu_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::log_softmax> {
    tensor_log_softmax_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_log_softmax_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::lp_normalization> {
    tensor_lp_normalization_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_lp_normalization_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::lrn> {
    tensor_lrn_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_lrn_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::lstm> {
    tensor_lstm_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_lstm_op_t op;
        op.direction =
            static_cast<lstmdirection_t>(reader.read_unaligned<uint32_t>());
        op.layout =
            static_cast<lstmlayout_t>(reader.read_unaligned<uint32_t>());
        op.activations = reader.read_string_array();
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::mat_mul> {
    tensor_mat_mul_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_mat_mul_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::mat_mul_shape> {
    tensor_mat_mul_shape_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_mat_mul_shape_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::normal> {
    tensor_normal_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_normal_op_t op;
        op.type = static_cast<typecode_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::normal_like> {
    tensor_normal_like_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_normal_like_op_t op;
        op.type = static_cast<typecode_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::one_hot> {
    tensor_one_hot_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_one_hot_op_t op;
        op.one_hot_mode =
            static_cast<one_hot_mode_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::pad> {
    tensor_pad_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_pad_op_t op;
        op.pad_mode = static_cast<pad_mode_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::prelu> {
    tensor_prelu_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_prelu_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::prod> {
    tensor_prod_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_prod_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::quant_param_of> {
    tensor_quant_param_of_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_quant_param_of_op_t op;
        op.quant_mode =
            static_cast<quant_mode_t>(reader.read_unaligned<uint32_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::quantize> {
    tensor_quantize_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_quantize_op_t op;
        op.target_type =
            static_cast<typecode_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::range> {
    tensor_range_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_range_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::range_of> {
    tensor_range_of_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_range_of_op_t op;
        op.is_range_of_weight = reader.read_unaligned<bool>();
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::rank> {
    tensor_rank_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_rank_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::reduce> {
    tensor_reduce_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_reduce_op_t op;
        op.reduce_op =
            static_cast<reduce_op_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::reduce_arg> {
    tensor_reduce_arg_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_reduce_arg_op_t op;
        op.reduce_arg_op =
            static_cast<reduce_arg_op_t>(reader.read_unaligned<uint8_t>());
        op.dest_type =
            static_cast<typecode_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::reduce_window2d> {
    tensor_reduce_window2d_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_reduce_window2d_op_t op;
        op.reduce_op =
            static_cast<reduce_op_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::relu> {
    tensor_relu_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_relu_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::relu6> {
    tensor_relu6_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_relu6_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::require> {
    tensor_require_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_require_op_t op;
        op.message = reader.read_string();
        op.can_fold_const_call = reader.read_unaligned<bool>();
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::reshape> {
    tensor_reshape_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_reshape_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::reshape_shape> {
    tensor_reshape_shape_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_reshape_shape_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::resize_image> {
    tensor_resize_image_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_resize_image_op_t op;
        op.resize_mode =
            static_cast<image_resize_mode_t>(reader.read_unaligned<uint8_t>());
        op.transformation_mode =
            static_cast<image_resize_transformation_mode_t>(
                reader.read_unaligned<uint32_t>());
        op.nearest_mode = static_cast<image_resize_nearest_mode_t>(
            reader.read_unaligned<uint32_t>());
        op.is_tfresize = reader.read_unaligned<bool>();
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::reverse_sequence> {
    tensor_reverse_sequence_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_reverse_sequence_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::scatter_nd> {
    tensor_scatter_nd_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_scatter_nd_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::select> {
    tensor_select_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_select_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::selu> {
    tensor_selu_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_selu_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::shape_of> {
    tensor_shape_of_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_shape_of_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::sigmoid> {
    tensor_sigmoid_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_sigmoid_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::size_of> {
    tensor_size_of_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_size_of_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::slice> {
    tensor_slice_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_slice_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::softmax> {
    tensor_softmax_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_softmax_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::softplus> {
    tensor_softplus_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_softplus_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::softsign> {
    tensor_softsign_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_softsign_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::space_to_batch> {
    tensor_space_to_batch_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_space_to_batch_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::split> {
    tensor_split_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_split_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::squeeze> {
    tensor_squeeze_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_squeeze_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::squeeze_shape> {
    tensor_squeeze_shape_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_squeeze_shape_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::stack> {
    tensor_stack_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_stack_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::swish> {
    tensor_swish_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_swish_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::tile> {
    tensor_tile_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_tile_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::top_k> {
    tensor_top_k_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_top_k_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::transpose> {
    tensor_transpose_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_transpose_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::transpose_shape> {
    tensor_transpose_shape_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_transpose_shape_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::trilu> {
    tensor_trilu_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_trilu_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::unary> {
    tensor_unary_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_unary_op_t op;
        op.unary_op = static_cast<unary_op_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::uniform> {
    tensor_uniform_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_uniform_op_t op;
        op.type = static_cast<typecode_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::uniform_like> {
    tensor_uniform_like_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_uniform_like_op_t op;
        op.type = static_cast<typecode_t>(reader.read_unaligned<uint8_t>());
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::unsqueeze> {
    tensor_unsqueeze_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_unsqueeze_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::unsqueeze_shape> {
    tensor_unsqueeze_shape_op_t
    operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_unsqueeze_shape_op_t op;
        return op;
    }
};

template <> struct tensor_op_reader<tensor_function_t::where> {
    tensor_where_op_t operator()(NNCASE_UNUSED span_reader &reader) const {
        tensor_where_op_t op;
        op.is_tf_where = reader.read_unaligned<bool>();
        return op;
    }
};

class NNCASE_API tensor_op_visitor {
  public:
    result<void> visit(tensor_function_t tensor_funct,
                       span_reader &reader) noexcept;

    virtual result<void>
    visit(NNCASE_UNUSED const tensor_batch_normalization_op_t &op) noexcept {
        return default_visit(tensor_function_t::batch_normalization, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_batch_to_space_op_t &op) noexcept {
        return default_visit(tensor_function_t::batch_to_space, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_binary_op_t &op) noexcept {
        return default_visit(tensor_function_t::binary, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_bitcast_op_t &op) noexcept {
        return default_visit(tensor_function_t::bitcast, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_broadcast_op_t &op) noexcept {
        return default_visit(tensor_function_t::broadcast, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_broadcast_shape_op_t &op) noexcept {
        return default_visit(tensor_function_t::broadcast_shape, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_bucket_pad_op_t &op) noexcept {
        return default_visit(tensor_function_t::bucket_pad, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_cast_op_t &op) noexcept {
        return default_visit(tensor_function_t::cast, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_celu_op_t &op) noexcept {
        return default_visit(tensor_function_t::celu, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_clamp_op_t &op) noexcept {
        return default_visit(tensor_function_t::clamp, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_compare_op_t &op) noexcept {
        return default_visit(tensor_function_t::compare, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_concat_op_t &op) noexcept {
        return default_visit(tensor_function_t::concat, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_condition_op_t &op) noexcept {
        return default_visit(tensor_function_t::condition, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_constant_of_shape_op_t &op) noexcept {
        return default_visit(tensor_function_t::constant_of_shape, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_conv2d_op_t &op) noexcept {
        return default_visit(tensor_function_t::conv2d, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_conv2d_shape_op_t &op) noexcept {
        return default_visit(tensor_function_t::conv2d_shape, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_conv2d_transpose_op_t &op) noexcept {
        return default_visit(tensor_function_t::conv2d_transpose, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_conv2d_transpose_shape_op_t &op) noexcept {
        return default_visit(tensor_function_t::conv2d_transpose_shape, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_cum_sum_op_t &op) noexcept {
        return default_visit(tensor_function_t::cum_sum, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_dequantize_op_t &op) noexcept {
        return default_visit(tensor_function_t::dequantize, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_elu_op_t &op) noexcept {
        return default_visit(tensor_function_t::elu, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_erf_op_t &op) noexcept {
        return default_visit(tensor_function_t::erf, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_expand_op_t &op) noexcept {
        return default_visit(tensor_function_t::expand, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_fake_dequantize_op_t &op) noexcept {
        return default_visit(tensor_function_t::fake_dequantize, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_fake_quantize_op_t &op) noexcept {
        return default_visit(tensor_function_t::fake_quantize, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_fix_shape_op_t &op) noexcept {
        return default_visit(tensor_function_t::fix_shape, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_flatten_op_t &op) noexcept {
        return default_visit(tensor_function_t::flatten, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_gather_op_t &op) noexcept {
        return default_visit(tensor_function_t::gather, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_gather_elements_op_t &op) noexcept {
        return default_visit(tensor_function_t::gather_elements, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_gather_nd_op_t &op) noexcept {
        return default_visit(tensor_function_t::gather_nd, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_gelu_op_t &op) noexcept {
        return default_visit(tensor_function_t::gelu, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_get_item_op_t &op) noexcept {
        return default_visit(tensor_function_t::get_item, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_get_paddings_op_t &op) noexcept {
        return default_visit(tensor_function_t::get_paddings, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_hard_sigmoid_op_t &op) noexcept {
        return default_visit(tensor_function_t::hard_sigmoid, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_hard_swish_op_t &op) noexcept {
        return default_visit(tensor_function_t::hard_swish, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_hardmax_op_t &op) noexcept {
        return default_visit(tensor_function_t::hardmax, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_index_of_op_t &op) noexcept {
        return default_visit(tensor_function_t::index_of, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_instance_normalization_op_t &op) noexcept {
        return default_visit(tensor_function_t::instance_normalization, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_l2_normalization_op_t &op) noexcept {
        return default_visit(tensor_function_t::l2_normalization, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_layer_norm_op_t &op) noexcept {
        return default_visit(tensor_function_t::layer_norm, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_leaky_relu_op_t &op) noexcept {
        return default_visit(tensor_function_t::leaky_relu, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_log_softmax_op_t &op) noexcept {
        return default_visit(tensor_function_t::log_softmax, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_lp_normalization_op_t &op) noexcept {
        return default_visit(tensor_function_t::lp_normalization, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_lrn_op_t &op) noexcept {
        return default_visit(tensor_function_t::lrn, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_lstm_op_t &op) noexcept {
        return default_visit(tensor_function_t::lstm, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_mat_mul_op_t &op) noexcept {
        return default_visit(tensor_function_t::mat_mul, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_mat_mul_shape_op_t &op) noexcept {
        return default_visit(tensor_function_t::mat_mul_shape, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_normal_op_t &op) noexcept {
        return default_visit(tensor_function_t::normal, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_normal_like_op_t &op) noexcept {
        return default_visit(tensor_function_t::normal_like, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_one_hot_op_t &op) noexcept {
        return default_visit(tensor_function_t::one_hot, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_pad_op_t &op) noexcept {
        return default_visit(tensor_function_t::pad, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_prelu_op_t &op) noexcept {
        return default_visit(tensor_function_t::prelu, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_prod_op_t &op) noexcept {
        return default_visit(tensor_function_t::prod, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_quant_param_of_op_t &op) noexcept {
        return default_visit(tensor_function_t::quant_param_of, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_quantize_op_t &op) noexcept {
        return default_visit(tensor_function_t::quantize, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_range_op_t &op) noexcept {
        return default_visit(tensor_function_t::range, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_range_of_op_t &op) noexcept {
        return default_visit(tensor_function_t::range_of, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_rank_op_t &op) noexcept {
        return default_visit(tensor_function_t::rank, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_reduce_op_t &op) noexcept {
        return default_visit(tensor_function_t::reduce, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_reduce_arg_op_t &op) noexcept {
        return default_visit(tensor_function_t::reduce_arg, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_reduce_window2d_op_t &op) noexcept {
        return default_visit(tensor_function_t::reduce_window2d, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_relu_op_t &op) noexcept {
        return default_visit(tensor_function_t::relu, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_relu6_op_t &op) noexcept {
        return default_visit(tensor_function_t::relu6, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_require_op_t &op) noexcept {
        return default_visit(tensor_function_t::require, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_reshape_op_t &op) noexcept {
        return default_visit(tensor_function_t::reshape, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_reshape_shape_op_t &op) noexcept {
        return default_visit(tensor_function_t::reshape_shape, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_resize_image_op_t &op) noexcept {
        return default_visit(tensor_function_t::resize_image, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_reverse_sequence_op_t &op) noexcept {
        return default_visit(tensor_function_t::reverse_sequence, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_scatter_nd_op_t &op) noexcept {
        return default_visit(tensor_function_t::scatter_nd, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_select_op_t &op) noexcept {
        return default_visit(tensor_function_t::select, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_selu_op_t &op) noexcept {
        return default_visit(tensor_function_t::selu, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_shape_of_op_t &op) noexcept {
        return default_visit(tensor_function_t::shape_of, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_sigmoid_op_t &op) noexcept {
        return default_visit(tensor_function_t::sigmoid, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_size_of_op_t &op) noexcept {
        return default_visit(tensor_function_t::size_of, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_slice_op_t &op) noexcept {
        return default_visit(tensor_function_t::slice, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_softmax_op_t &op) noexcept {
        return default_visit(tensor_function_t::softmax, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_softplus_op_t &op) noexcept {
        return default_visit(tensor_function_t::softplus, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_softsign_op_t &op) noexcept {
        return default_visit(tensor_function_t::softsign, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_space_to_batch_op_t &op) noexcept {
        return default_visit(tensor_function_t::space_to_batch, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_split_op_t &op) noexcept {
        return default_visit(tensor_function_t::split, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_squeeze_op_t &op) noexcept {
        return default_visit(tensor_function_t::squeeze, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_squeeze_shape_op_t &op) noexcept {
        return default_visit(tensor_function_t::squeeze_shape, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_stack_op_t &op) noexcept {
        return default_visit(tensor_function_t::stack, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_swish_op_t &op) noexcept {
        return default_visit(tensor_function_t::swish, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_tile_op_t &op) noexcept {
        return default_visit(tensor_function_t::tile, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_top_k_op_t &op) noexcept {
        return default_visit(tensor_function_t::top_k, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_transpose_op_t &op) noexcept {
        return default_visit(tensor_function_t::transpose, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_transpose_shape_op_t &op) noexcept {
        return default_visit(tensor_function_t::transpose_shape, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_trilu_op_t &op) noexcept {
        return default_visit(tensor_function_t::trilu, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_unary_op_t &op) noexcept {
        return default_visit(tensor_function_t::unary, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_uniform_op_t &op) noexcept {
        return default_visit(tensor_function_t::uniform, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_uniform_like_op_t &op) noexcept {
        return default_visit(tensor_function_t::uniform_like, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_unsqueeze_op_t &op) noexcept {
        return default_visit(tensor_function_t::unsqueeze, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_unsqueeze_shape_op_t &op) noexcept {
        return default_visit(tensor_function_t::unsqueeze_shape, &op);
    }
    virtual result<void>
    visit(NNCASE_UNUSED const tensor_where_op_t &op) noexcept {
        return default_visit(tensor_function_t::where, &op);
    }

  protected:
    virtual result<void>
    default_visit(NNCASE_UNUSED tensor_function_t tensor_funct,
                  NNCASE_UNUSED const void *op) noexcept {
        return err(std::errc::not_supported);
    }
};

END_NS_NNCASE_RT_MODULE
