MODE: INLINE

void register_error_constants(); // regerror.cc, because fucking xsubpp removes preprocessor directives

MODULE = XS::Framework                PACKAGE = XS::STL::ErrorCode
PROTOTYPES: DISABLE

BOOT {
    register_error_constants();
}

std::error_code new (SV*, int ec, const std::error_category* category) {
    if (!category) throw "category required";
    RETVAL = std::error_code(ec, *category);
}

int value (std::error_code ec) {
    RETVAL = ec.value();
}

const std::error_category* category (std::error_code ec) {
    RETVAL = &ec.category();
}

std::string message (std::error_code ec) {
    RETVAL = ec.message();
}

std::string _op_string (std::error_code ec, ...) {
    RETVAL = ec.message();
    RETVAL += " (";
    RETVAL += std::to_string(ec.value());
    RETVAL += ":";
    RETVAL += ec.category().name();
    RETVAL += ")";
}

bool _op_bool (std::error_code ec, ...) {
    RETVAL = ec.value();
}

bool _op_eq (std::error_code ec1, Sv sv_ec2, ...) {
    if (sv_ec2.is_object_ref()) {
        Object ec2 = sv_ec2;
        auto class_name = ec2.stash().name();
        if (class_name == "XS::ErrorCode") {
            RETVAL = ec1 & xs::in<ErrorCode>(sv_ec2);
        } else if (class_name == "XS::STL::ErrorCode") {
            RETVAL = ec1 == xs::in<std::error_code>(sv_ec2);
        } else {
            RETVAL = false;
        }
    } else if (SvIOK(sv_ec2)) {
        int code = Simple(sv_ec2);
        RETVAL = ec1.value() == code;
    } else {
        RETVAL = false;
    }
}

MODULE = XS::Framework                PACKAGE = XS::STL::ErrorCategory
PROTOTYPES: DISABLE

const char* std::error_category::name () : const

std::string std::error_category::message (int ec) : const

std::string std::error_category::_op_string (...) : const {
    RETVAL = THIS->name();
}

bool std::error_category::_op_eq (const std::error_category* oth, ...) : const {
    RETVAL = *THIS == *oth;
}

MODULE = XS::Framework                PACKAGE = XS::ErrorCode
PROTOTYPES: DISABLE

ErrorCode new (SV*, std::error_code c, ErrorCode next = ErrorCode()) {
    if (next) RETVAL = ErrorCode(c, next);
    else RETVAL = ErrorCode(c);
}

int value (ErrorCode ec) {
    RETVAL = ec.value();
}

const std::error_category* category (ErrorCode ec) {
    RETVAL = &ec.category();
}

std::string message (ErrorCode ec) {
    RETVAL = ec.message();
}

std::error_code code (ErrorCode ec) {
    RETVAL = ec.code();
}

ErrorCode next (ErrorCode ec) {
    RETVAL = ec.next();
}

std::string _op_string (ErrorCode ec, ...) {
    if (!ec) XSRETURN_UNDEF;
    RETVAL = ec.what();
}

bool _op_bool (ErrorCode ec, ...) {
    RETVAL = ec.value();
}

bool _op_eq (ErrorCode ec1, Sv sv_ec2, ...) {
    if (sv_ec2.is_object_ref()) {
        Object ec2 = sv_ec2;
        auto class_name = ec2.stash().name();
        if (class_name == "XS::ErrorCode") {
            RETVAL = ec1 == xs::in<ErrorCode>(sv_ec2);
        } else if (class_name == "XS::STL::ErrorCode") {
            RETVAL = ec1 & xs::in<std::error_code>(sv_ec2);
        } else {
            RETVAL = false;
        }
    } else if (SvIOK(sv_ec2)) {
        int code = Simple(sv_ec2);
        RETVAL = ec1.value() == code;
    } else {
        RETVAL = false;
    }
}

bool contains(ErrorCode ec, std::error_code c) {
    RETVAL = ec.contains(c);
}