1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//! Definitions for the compiled Ruby macros.
//!
//! Since macros are rely on the C preprocessor, they are not automatically
//! available to Rust. This module compiles a tiny snippet of C code that is
//! used to generate the Ruby macros, so they can be used in Rust.

use std::os::raw::{c_char, c_long};

use crate::{ruby_value_type, ID, VALUE};

extern "C" {

    /// Queries if the given object is of given type.
    ///
    /// @param[in]  obj    An object.
    /// @param[in]  t      A type.
    /// @retval     true   `obj` is of type `t`.
    /// @retval     false  Otherwise.
    ///
    /// @internal
    ///
    /// This  function is  a super-duper  hot  path.  Optimised  targeting modern  C
    /// compilers and x86_64 architecture.
    #[link_name = "ruby_macros_RB_TYPE_P"]
    pub fn RB_TYPE_P(obj: VALUE, t: ruby_value_type) -> bool;

    /// Queries if the object is an instance of ::ruby_macros_cInteger.
    ///
    /// @param[in]  obj    Object in question.
    /// @retval     true   It is.
    /// @retval     false  It isn't.
    #[link_name = "ruby_macros_RB_INTEGER_TYPE_P"]
    pub fn RB_INTEGER_TYPE_P(obj: VALUE) -> bool;

    /// Queries if the object is an instance of ::ruby_macros_cFloat.
    ///
    /// @param[in]  obj    Object in question.
    /// @retval     true   It is.
    /// @retval     false  It isn't.
    #[link_name = "ruby_macros_RB_FLOAT_TYPE_P"]
    pub fn RB_FLOAT_TYPE_P(obj: VALUE) -> bool;

    /// Queries if the object is an instance of ::ruby_macros_cSymbol.
    ///
    /// @param[in]  obj    Object in question.
    /// @retval     true   It is.
    /// @retval     false  It isn't.
    #[link_name = "ruby_macros_SYMBOL_P"]
    pub fn SYMBOL_P(obj: VALUE) -> bool;

    /// Checks if the given object is nil.
    ///
    /// @param[in]  obj    An arbitrary ruby object.
    /// @retval     true   `obj` is ::Qnil.
    /// @retval     false  Anything else.
    #[link_name = "ruby_macros_NIL_P"]
    pub fn NIL_P(obj: VALUE) -> bool;

    /// Emulates Ruby's "if" statement.
    ///
    /// @param[in]  obj    An arbitrary ruby object.
    /// @retval     false  `obj` is either ::Qfalse or ::Qnil.
    /// @retval     true   Anything else.
    ///
    /// @internal
    ///
    /// It HAS to be `__attribute__((const))` in  order for clang to properly deduce
    /// `__builtin_assume()`.
    #[link_name = "ruby_macros_RB_TEST"]
    pub fn RB_TEST(obj: VALUE) -> bool;

    /// Allocates an instance of ::rb_cSymbol that has the given id.
    ///
    /// @param[in]  id           An id.
    /// @retval     Qfalse  No such id ever existed in the history.
    /// @retval     Otherwise    An allocated ::rb_cSymbol instance.
    #[link_name = "ruby_macros_ID2SYM"]
    pub fn ID2SYM(obj: ID) -> VALUE;

    /// Converts an instance of ::rb_cSymbol into an ::ID.
    ///
    /// @param[in]  obj            An instance of ::rb_cSymbol.
    /// @exception  rb_eTypeError  `obj` is not an instance of ::rb_cSymbol.
    /// @return     An ::ID of the identical symbol.
    #[link_name = "ruby_macros_SYM2ID"]
    pub fn SYM2ID(obj: ID) -> VALUE;

    /// Queries the contents pointer of the string.
    ///
    /// @param[in]  str  String in question.
    /// @return     Pointer to its contents.
    /// @pre        `str` must be an instance of ::RString.
    #[link_name = "ruby_macros_RSTRING_PTR"]
    pub fn RSTRING_PTR(obj: VALUE) -> *mut c_char;

    /// Queries the length of the string.
    ///
    /// @param[in]  str  String in question.
    /// @return     Its length, in bytes.
    /// @pre        `str` must be an instance of ::RString.
    #[link_name = "ruby_macros_RSTRING_LEN"]
    pub fn RSTRING_LEN(obj: VALUE) -> c_long;

    /// Queries the length of the array.
    ///
    /// @param[in]  a  Array in question.
    /// @return     Its number of elements.
    /// @pre        `a` must be an instance of ::RArray.
    #[link_name = "ruby_macros_RARRAY_LEN"]
    pub fn RARRAY_LEN(a: VALUE) -> c_long;
}