split internal.h into files
[ruby.git] / internal / struct.h
blobf63b45007e2b68904afd26554f63b1e800256014
1 #ifndef INTERNAL_STRUCT_H /* -*- C -*- */
2 #define INTERNAL_STRUCT_H
3 /**
4 * @file
5 * @brief Internal header for Struct.
6 * @author \@shyouhei
7 * @copyright This file is a part of the programming language Ruby.
8 * Permission is hereby granted, to either redistribute and/or
9 * modify this file, provided that the conditions mentioned in the
10 * file COPYING are met. Consult the file for details.
13 #define RSTRUCT_EMBED_LEN_MAX RSTRUCT_EMBED_LEN_MAX
14 #define RSTRUCT_EMBED_LEN_MASK RSTRUCT_EMBED_LEN_MASK
15 #define RSTRUCT_EMBED_LEN_SHIFT RSTRUCT_EMBED_LEN_SHIFT
17 enum {
18 RSTRUCT_EMBED_LEN_MAX = RVALUE_EMBED_LEN_MAX,
19 RSTRUCT_EMBED_LEN_MASK = (RUBY_FL_USER2|RUBY_FL_USER1),
20 RSTRUCT_EMBED_LEN_SHIFT = (RUBY_FL_USHIFT+1),
21 RSTRUCT_TRANSIENT_FLAG = FL_USER3,
23 RSTRUCT_ENUM_END
26 #if USE_TRANSIENT_HEAP
27 #define RSTRUCT_TRANSIENT_P(st) FL_TEST_RAW((obj), RSTRUCT_TRANSIENT_FLAG)
28 #define RSTRUCT_TRANSIENT_SET(st) FL_SET_RAW((st), RSTRUCT_TRANSIENT_FLAG)
29 #define RSTRUCT_TRANSIENT_UNSET(st) FL_UNSET_RAW((st), RSTRUCT_TRANSIENT_FLAG)
30 #else
31 #define RSTRUCT_TRANSIENT_P(st) 0
32 #define RSTRUCT_TRANSIENT_SET(st) ((void)0)
33 #define RSTRUCT_TRANSIENT_UNSET(st) ((void)0)
34 #endif
36 struct RStruct {
37 struct RBasic basic;
38 union {
39 struct {
40 long len;
41 const VALUE *ptr;
42 } heap;
43 const VALUE ary[RSTRUCT_EMBED_LEN_MAX];
44 } as;
47 #undef RSTRUCT_LEN
48 #undef RSTRUCT_PTR
49 #undef RSTRUCT_SET
50 #undef RSTRUCT_GET
51 #define RSTRUCT_EMBED_LEN(st) \
52 (long)((RBASIC(st)->flags >> RSTRUCT_EMBED_LEN_SHIFT) & \
53 (RSTRUCT_EMBED_LEN_MASK >> RSTRUCT_EMBED_LEN_SHIFT))
54 #define RSTRUCT_LEN(st) rb_struct_len(st)
55 #define RSTRUCT_LENINT(st) rb_long2int(RSTRUCT_LEN(st))
56 #define RSTRUCT_CONST_PTR(st) rb_struct_const_ptr(st)
57 #define RSTRUCT_PTR(st) ((VALUE *)RSTRUCT_CONST_PTR(RB_OBJ_WB_UNPROTECT_FOR(STRUCT, st)))
58 #define RSTRUCT_SET(st, idx, v) RB_OBJ_WRITE(st, &RSTRUCT_CONST_PTR(st)[idx], (v))
59 #define RSTRUCT_GET(st, idx) (RSTRUCT_CONST_PTR(st)[idx])
60 #define RSTRUCT(obj) (R_CAST(RStruct)(obj))
62 /* struct.c */
63 VALUE rb_struct_init_copy(VALUE copy, VALUE s);
64 VALUE rb_struct_lookup(VALUE s, VALUE idx);
65 VALUE rb_struct_s_keyword_init(VALUE klass);
67 static inline long
68 rb_struct_len(VALUE st)
70 return (RBASIC(st)->flags & RSTRUCT_EMBED_LEN_MASK) ?
71 RSTRUCT_EMBED_LEN(st) : RSTRUCT(st)->as.heap.len;
74 static inline const VALUE *
75 rb_struct_const_ptr(VALUE st)
77 return FIX_CONST_VALUE_PTR((RBASIC(st)->flags & RSTRUCT_EMBED_LEN_MASK) ?
78 RSTRUCT(st)->as.ary : RSTRUCT(st)->as.heap.ptr);
81 static inline const VALUE *
82 rb_struct_const_heap_ptr(VALUE st)
84 /* TODO: check embed on debug mode */
85 return RSTRUCT(st)->as.heap.ptr;
88 #endif /* INTERNAL_STRUCT_H */