-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathstruct.h
225 lines (209 loc) · 9.2 KB
/
struct.h
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#ifndef RBIMPL_INTERN_STRUCT_H /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_STRUCT_H
/**
* @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
* modify this file, provided that the conditions mentioned in the
* file COPYING are met. Consult the file for details.
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
* implementation details. Don't take them as canon. They could
* rapidly appear then vanish. The name (path) of this header file
* is also an implementation detail. Do not expect it to persist
* at the place it is now. Developers are free to move it anywhere
* anytime at will.
* @note To ruby-core: remember that this header can be possibly
* recursively included from extension libraries written in C++.
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
* @brief Public APIs related to ::rb_cStruct.
*/
#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/intern/vm.h" /* rb_alloc_func_t */
#include "ruby/internal/value.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* struct.c */
/**
* Creates an instance of the given struct.
*
* @param[in] klass The class of the instance to allocate.
* @param[in] ... The fields.
* @return Allocated instance of `klass`.
* @pre `klass` must be a subclass of ::rb_cStruct.
* @note Number of variadic arguments must much that of the passed klass'
* fields.
*/
VALUE rb_struct_new(VALUE klass, ...);
/**
* Defines a struct class.
*
* @param[in] name Name of the class.
* @param[in] ... Arbitrary number of `const char*`, terminated by
* NULL. Each of which are the name of fields.
* @exception rb_eNameError `name` is not a constant name.
* @exception rb_eTypeError `name` is already taken.
* @exception rb_eArgError Duplicated field name.
* @return The defined class.
* @post Global toplevel constant `name` is defined.
* @note `name` is allowed to be a null pointer. This function creates
* an anonymous struct class then.
* @note The GC does not collect nor move classes returned by this
* function. They are immortal.
*
* @internal
*
* Not seriously checked but it seems this function does not share its
* implementation with how `Struct.new` is implemented...?
*/
VALUE rb_struct_define(const char *name, ...);
RBIMPL_ATTR_NONNULL((2))
/**
* Identical to rb_struct_define(), except it defines the class under the
* specified namespace instead of global toplevel.
*
* @param[out] space Namespace that the defining class shall reside.
* @param[in] name Name of the class.
* @param[in] ... Arbitrary number of `const char*`, terminated by
* NULL. Each of which are the name of fields.
* @exception rb_eNameError `name` is not a constant name.
* @exception rb_eTypeError `name` is already taken.
* @exception rb_eArgError Duplicated field name.
* @return The defined class.
* @post `name` is a constant under `space`.
* @note In contrast to rb_struct_define(), it doesn't make any sense to
* pass a null pointer to this function.
* @note The GC does not collect nor move classes returned by this
* function. They are immortal.
*/
VALUE rb_struct_define_under(VALUE space, const char *name, ...);
/**
* Identical to rb_struct_new(), except it takes the field values as a Ruby
* array.
*
* @param[in] klass The class of the instance to allocate.
* @param[in] values Field values.
* @return Allocated instance of `klass`.
* @pre `klass` must be a subclass of ::rb_cStruct.
* @pre `values` must be an instance of struct ::RArray.
*/
VALUE rb_struct_alloc(VALUE klass, VALUE values);
/**
* Mass-assigns a struct's fields.
*
* @param[out] self An instance of a struct class to squash.
* @param[in] values New values.
* @return ::RUBY_Qnil.
*/
VALUE rb_struct_initialize(VALUE self, VALUE values);
/**
* Identical to rb_struct_aref(), except it takes ::ID instead of ::VALUE.
*
* @param[in] self An instance of a struct class.
* @param[in] key Key to query.
* @exception rb_eTypeError `self` is not a struct.
* @exception rb_eNameError No such field.
* @return The value stored at `key` in `self`.
*/
VALUE rb_struct_getmember(VALUE self, ID key);
/**
* Queries the list of the names of the fields of the given struct class.
*
* @param[in] klass A subclass of ::rb_cStruct.
* @return The list of the names of the fields of `klass`.
*/
VALUE rb_struct_s_members(VALUE klass);
/**
* Queries the list of the names of the fields of the class of the given struct
* object. This is almost the same as calling rb_struct_s_members() over the
* class of the receiver.
*
* @internal
*
* "Almost"? What exactly is the difference?
*
* @endinternal
*
* @param[in] self An instance of a subclass of ::rb_cStruct.
* @return The list of the names of the fields.
*/
VALUE rb_struct_members(VALUE self);
/**
* Allocates an instance of the given class. This consequential name is of
* course because rb_struct_alloc() not only allocates but also initialises an
* instance. The API design is broken.
*
* @param[in] klass A subclass of ::rb_cStruct.
* @return An allocated instance of `klass`, not initialised.
*/
VALUE rb_struct_alloc_noinit(VALUE klass);
/**
* Identical to rb_struct_define(), except it does not define accessor methods.
* You have to define them yourself. Forget about the allocator function
* parameter; it is for internal use only. Extension libraries are unable to
* properly allocate a ruby struct, because `RStruct` is opaque.
*
* @internal
*
* Several flags must be set up properly for ::RUBY_T_STRUCT objects, which are
* also missing for extension libraries.
*
* @endinternal
*
* @param[in] name Name of the class.
* @param[in] super Superclass of the defining class.
* @param[in] func Must be 0 for extension libraries.
* @param[in] ... Arbitrary number of `const char*`, terminated by
* NULL. Each of which are the name of fields.
* @exception rb_eNameError `name` is not a constant name.
* @exception rb_eTypeError `name` is already taken.
* @exception rb_eArgError Duplicated field name.
* @return The defined class.
* @post Global toplevel constant `name` is defined.
* @note `name` is allowed to be a null pointer. This function creates
* an anonymous struct class then.
*/
VALUE rb_struct_define_without_accessor(const char *name, VALUE super, rb_alloc_func_t func, ...);
RBIMPL_ATTR_NONNULL((2))
/**
* Identical to rb_struct_define_without_accessor(), except it defines the
* class under the specified namespace instead of global toplevel. It can also
* be seen as a routine identical to rb_struct_define_under(), except it does
* not define accessor methods.
*
* @param[out] outer Namespace that the defining class shall reside.
* @param[in] class_name Name of the class.
* @param[in] super Superclass of the defining class.
* @param[in] alloc Must be 0 for extension libraries.
* @param[in] ... Arbitrary number of `const char*`, terminated by
* NULL. Each of which are the name of fields.
* @exception rb_eNameError `class_name` is not a constant name.
* @exception rb_eTypeError `class_name` is already taken.
* @exception rb_eArgError Duplicated field name.
* @return The defined class.
* @post `class_name` is a constant under `outer`.
* @note In contrast to rb_struct_define_without_accessor(), it doesn't
* make any sense to pass a null name.
* @note The GC does not collect nor move classes returned by this
* function. They are immortal.
*/
VALUE rb_struct_define_without_accessor_under(VALUE outer, const char *class_name, VALUE super, rb_alloc_func_t alloc, ...);
/**
* Defines an anonymous data class.
*
* @endinternal
*
* @param[in] super Superclass of the defining class. Must be a
* descendant of ::rb_cData, or 0 as ::rb_cData.
* @param[in] ... Arbitrary number of `const char*`, terminated by
* NULL. Each of which are the name of fields.
* @exception rb_eArgError Duplicated field name.
* @return The defined class.
* @note The GC does not collect nor move classes returned by this
* function. They are immortal.
*/
VALUE rb_data_define(VALUE super, ...);
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_STRUCT_H */